TCP WSASend 完成标准
Posted
技术标签:
【中文标题】TCP WSASend 完成标准【英文标题】:TCP WSASend Completion Criteria 【发布时间】:2014-01-13 14:01:28 【问题描述】:我无法找到 TCP WSASend 调用完成意味着什么的规范。 WSASend 操作的完成是否需要收到 ACK 响应?
此问题与 200 毫秒 - 2 秒 ping 超时的较慢网络有关。调用 WSASend 完成回调是否需要 200 毫秒 - 2 秒(或使用任何完成机制)?或者也许只有在某些数据包上,Windows 才会等待 ACK 并认为 WSASend 操作对所有其他数据包完成得更快?
确切的行为对缓冲区生命周期管理有很大影响,进而对性能(锁定、分配/解除分配和引用计数)产生重大影响。
【问题讨论】:
【参考方案1】:WSASend 不保证以下内容:
-
数据已发送(可能已被缓冲)
已收到(可能已丢失)
接收应用程序处理了它(发件人原则上永远不会知道这一点)
它不需要往返。事实上,启用 nagling 后,总是会缓冲 200 毫秒的少量数据,希望应用程序发送更多数据。 WSASend 必须快速返回,这样 nagling 才有机会发挥作用。
如果您需要确认,请更改应用程序协议,以便您得到确认。没有其他办法。
澄清一下,即使没有 nagling (TCP_NODELAY),您的发送操作也不会收到 ACK。它将被发送到网络,但远程端不知道它应该 ACK。 TCP 没有办法说“请立即确认此数据”。正在发送的数据并不意味着它将永远被接收。数据被推到黑洞后一秒钟网络可能会掉线。
【讨论】:
【参考方案2】:没有记录。它可能会有所不同,具体取决于您是否关闭了发送缓冲。但是,您始终需要注意获得WSASend()
完成所需的潜在时间,尤其是在您使用异步调用的情况下。详情请见this article of mine。
当 TCP 堆栈用完你的缓冲区时,你会得到一个 WSASend()
完成。如果您没有通过将SO_SNDBUF
设置为零来关闭发送缓冲,那么这可能意味着一旦堆栈将您的数据复制到其缓冲区中,您将获得完成。如果您关闭了发送缓冲,那么这可能意味着一旦您收到 ACK,您将获得完成(仅仅是因为堆栈应该需要您的缓冲区来进行任何潜在的重新传输)。但是,它没有记录在案。
【讨论】:
您认为TCP_NODELAY
会有所作为吗?
这可能意味着数据的发送速度会略微加快,因此可能会略微减少完成时间。以上是关于TCP WSASend 完成标准的主要内容,如果未能解决你的问题,请参考以下文章
具有多个缓冲区的 WSASend() - 可以完成不完整吗?
如何知道完成数据包是针对 WSASend() 还是 WSARecv() 还是 AcceptEx()?