Winsock 200毫秒延迟问题
Winsock 200ms delay issue
我发现WinSock发送呼叫可能会延迟200ms
来自MSDN:http://support.microsoft.com/kb/214397/en
Nagle算法:http://en.wikipedia.org/wiki/Nagle算法
问题摘要:
如果重复发送带有SO_ SNDBUF"0"选项的小消息(<MTU),发送功能块200ms。
我的问题:为什么第一次发送消息延迟200ms?
因为TCP在第一次发送呼叫之前是空闲的,所以我认为必须立即发送第一条消息。
但测试结果并不理想。
第一条消息也延迟了200ms,为什么?
谢谢你的回答。
添加一些详细信息:
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.
所以,我的期望是第一条消息立即发送,第二条消息等待第一条消息的确认200ms,以此类推
这错了吗?
通常TCP会将数据保存在发送缓冲区中,直到对等方对其进行确认。在您的情况下,没有发送缓冲区(因为SO_SNDBUF=0)。因此,TCP阻止发送方保留数据以备可能的重传。对等端的TCP堆栈使用"延迟确认"例程,并在200ms延迟后发送确认(或直到接收到2个带有数据的数据包而没有确认)。
因此,在对等方确认所有数据之前,发送方将被阻止。如果网络的RTT很长,或者发生数据包丢失,则可能需要超过200ms的时间。
延迟的全部目的是查看是否有更多数据可以添加到同一消息中。没有理由认为第一条消息应该是该规则的例外。
Nagle算法背后的想法是优化这样的情况:
- 在send()调用中发送1字节的数据
- 1毫秒后,用1字节的数据再次调用send()
- 1毫秒后,您再次调用send()
如果没有Nagle算法,它将导致3个单独的分组,每个分组具有几个字节的报头和只有1个字节的有用有效载荷。这将意味着大量的开销。
使用Nagle算法,相同的send()调用序列将只产生一个具有一些报头字节和3个有效载荷字节的数据包,从而减少了开销大小。但是,数据包将在您第一次通话后200毫秒发送。
Nagle算法的想法是在发送一小块数据后等待,预计您可能会想要发送更多数据。由于系统不知道你未来发送任何东西的计划,它会等待一段合理的时间(200毫秒),如果没有发送任何信息,它会发送实际的数据包,以免延迟太大。
如果你在不等待回复的情况下以小块的形式发送数据(例如逐行发送文本文件),该算法将对你的程序有益。这将大大减少通过网络发送的数据包数量和相关开销。
如果您的程序对响应时间敏感,并且不需要此优化,则可以通过使用TCP_NODELAY参数调用setsockopt()来安全地禁用它,甚至可以考虑使用UDP而不是TCP。
老实说,我不记得第一条消息也被延迟的行为。我使用了WinSock,数据运行得很顺利。他们可以用这种方式实现它,因为这并不违反任何标准。这就是答案。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 使用 FFMPEG 库到 UDP 流 mpeg2 ts 视频延迟/初始连接问题
- Winsock 200毫秒延迟问题
- 仅visual studio 2010中存在可延迟迭代器问题
- 设计问题:从低延迟的c++应用程序更新数据库
- c++预处理器延迟扩展问题
- Windows (c++)上窗口消息的问题(延迟)
- 具有延迟传播时间限制问题的分段树
- singleton的延迟初始化问题
- openCV-网络摄像头的视频捕获-延迟问题