TCP WSASend完成标准

时间:2014-01-13 14:01:29

标签: c++ sockets network-programming winsock

我无法找到TCP WSASend调用完成的含义规范。 WSASend操作的完成是否需要收到ACK响应?

这个问题与200ms-2s ping超时的较慢网络有关。是否需要200ms - 2s来调用WSASend完成回调(或者使用什么完成机制)?或者也许仅在某些数据包上,Windows会等待ACK并认为WSASend操作对所有其他数据包的完成速度要快得多吗?

确切的行为会对缓冲区生命周期管理产生重大影响,从而对性能产生重大影响(锁定,分配/释放和引用计数)。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

WSASend不保证以下内容:

  1. 数据已发送(可能已缓存)
  2. 收到它(它可能已经丢失)
  3. 接收申请处理了它(发件人原则上不知道这一点)
  4. 它不需要往返。实际上,在启用了nagling的情况下,少量数据总是被缓冲200ms,希望应用程序能够发送更多数据。 WSASend 必须快速返回,以便nagling有机会工作。

    如果您需要确认,请更改应用程序协议,以便获得确认。别无他法。

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