【问题标题】:TCP WSASend Completion CriteriaTCP WSASend 完成标准
【发布时间】:2023-03-08 09:42:01
【问题描述】:

我无法找到 TCP WSASend 调用完成意味着什么的规范。 WSASend 操作的完成是否需要收到 ACK 响应?

此问题与 200 毫秒 - 2 秒 ping 超时的较慢网络有关。调用 WSASend 完成回调是否需要 200 毫秒 - 2 秒(或使用任何完成机制)?或者也许只有在某些数据包上,Windows 才会等待 ACK 并认为 WSASend 操作对所有其他数据包完成得更快?

确切的行为对缓冲区生命周期管理有很大影响,进而对性能(锁定、分配/解除分配和引用计数)产生重大影响。

【问题讨论】:

    标签: c++ sockets network-programming winsock


    【解决方案1】:

    WSASend 不保证以下内容:

    1. 数据已发送(可能已被缓冲)
    2. 已收到(可能已丢失)
    3. 接收应用程序处理了它(发件人原则上永远不会知道这一点)

    它不需要往返。事实上,启用 nagling 后,总是会缓冲 200 毫秒的少量数据,希望应用程序发送更多数据。 WSASend 必须快速返回,这样 nagling 才有机会发挥作用。

    如果您需要确认,请更改应用程序协议,以便您得到确认。没有其他办法。

    澄清一下,即使没有 nagling (TCP_NODELAY),您的发送操作也不会收到 ACK。它将被发送到网络,但远程端不知道它应该 ACK。 TCP 没有办法说“请立即确认此数据”。正在发送的数据并不意味着它将永远被接收。数据被推到黑洞后一秒钟网络可能会掉线。

    【讨论】:

      【解决方案2】:

      没有记录。它可能会有所不同,具体取决于您是否关闭了发送缓冲。但是,您始终需要注意获得WSASend() 完成所需的潜在时间,尤其是在您使用异步调用的情况下。详情请见this article of mine

      当 TCP 堆栈用完你的缓冲区时,你会得到一个 WSASend() 完成。如果您没有通过将SO_SNDBUF 设置为零来关闭发送缓冲,那么这可能意味着一旦堆栈将您的数据复制到其缓冲区中,您将获得完成。如果您关闭了发送缓冲,那么这可能意味着一旦您收到 ACK,您将获得完成(仅仅是因为堆栈应该需要您的缓冲区来进行任何潜在的重新传输)。但是,它没有记录在案。

      【讨论】:

      • 您认为TCP_NODELAY 会有所作为吗?
      • 这可能意味着数据的发送速度会略微加快,因此可能会略微减少完成时间。
      猜你喜欢
      • 2021-08-05
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      相关资源
      最近更新 更多