首页 文章

Winsock 200ms延迟问题

提问于
浏览
3

我发现它可以在WinSock发送呼叫上延迟200ms

来自MSDN:http://support.microsoft.com/kb/214397/en

Nagle算法:http://en.wikipedia.org/wiki/Nagle's_algorithm

Issue summary

如果重复发送带有SO_SNDBUF“0”选项的小msg(<MTU),则发送功能块200ms .

My Question :为什么 first send message 延迟200ms?

因为TCP在第一次发送呼叫之前是空闲的,所以我认为必须立即发送第一条消息 .

但是不希望测试结果 .

第一条消息也延迟了200ms,为什么?

谢谢你的回答 .

Add some details

Naggle算法适用于以下小消息:

1. if wire is idle, send it immediately.
2. if formal message's ACK is not received, wait until ACK & send
3. Window's TCP ack delay mechanism send ack after 200ms.

所以,我的期望是第一个消息立即发送,第二个消息等待第一个消息的ack为200ms,依此类推 .

这是错的吗?

4 回答

  • 3

    通常,TCP会将数据保留在发送缓冲区中,直到它被对等方确认为止 . 在您的情况下,没有发送缓冲区(因为SO_SNDBUF = 0) . 因此TCP阻止发送方保留数据以进行可能的重传 . 对等体的TCP堆栈使用“Delayed ack”例程,并在200ms延迟后发送确认(或直到收到数据的2个数据包而没有执行) .

    因此,发送方将被阻止,直到所有数据都被对等方确认 . 如果网络的RTT很长,或者发生丢包,则可能需要200ms以上 .

  • 0

    延迟的重点是查看是否有更多数据可以添加到同一消息中 . 没有理由为什么第一条消息应该是这条规则的例外 .

  • 3

    Nagle算法背后的想法是优化这样的案例:

    • 您在send()调用中发送1个字节的数据

    • 1毫秒后,再次使用1字节数据调用send()

    • 再过1毫秒再次调用send()

    如果没有Nagle算法,它将产生3个独立的数据包,每个数据包具有几个字节的报头,只有1个字节的有用负载 . 这意味着很多开销 .

    使用Nagle算法,相同的send()调用序列将导致只有1个包含一些头字节和3个字节的有效负载,从而减少了开销大小 . 但是,数据包将在您第一次通话后200毫秒发送 .

    Nagle算法的想法是等待你发送一小块数据后期望你可能想要发送更多 . 由于系统不知道您将来发送任何内容的计划,它会等待一段合理的时间(200毫秒),如果不再发送任何内容,它会发送实际数据包,不会使延迟太大 .

    如果您在不等待回复的情况下以小块发送数据(例如,逐行发送文本文件),该算法将对您的程序有益 . 这将大大减少通过网络发送的数据包数量和相关开销 .

    如果您的程序对响应时间敏感并且不需要此优化,则可以通过使用TCP_NODELAY参数调用setsockopt()来安全地禁用它,甚至可以考虑使用UDP而不是TCP .

  • 4

    老实说,我不记得第一条消息也被延迟的行为 . 我使用WinSock,数据运行顺利 . 他们可以通过这种方式实现它,因为 this is not against of any standard . 这就是答案 .

相关问题