所以,当我遇到Nagle的算法时,我正在经历TCP的事情,并且延迟了针对小型数据包(1字节数据)的ACK。原因是,避免在网络上发送大量小数据包(Nagle)和捎带数据(延迟ACK)。然而,对于批量数据没有提及这些算法,即我写了> 8000字节。 4个问题:
这些算法是否仅适用于小型数据包?
例如,当我们执行写入(8000)时,TCP首先发送1500个字节(假设1500为MSS并且发生慢启动),在收到第一个ACK之前,它可以发送另一个1500数据字节,那么是不是违反了Nagle的?
接收方是否等待超时发送延迟的ACK或收到1500字节的数据后立即发送?
它如何知道何时延迟ACK?它是基于接收缓冲区中的字节吗?
谢谢!
答案 0 :(得分:12)
Nagle算法的想法是防止一次传输过多的小型数据包。延迟ACK(来自伯克利)的想法是避免在通过远程回声的Telnet连接进行键入时为每个字符发送单独的ACK,等待一段固定的时间用于反向的流量,在该方向上可以捎带ACK
两种算法的相互作用很糟糕。如果你做大发送,大发送,大发送,这工作正常。如果你发送,得到回复,发送,得到回复,这是正常的。如果你做小发,小发,得到回复,会有一个短暂的停顿。这是因为第二个小发送被Nagle算法延迟,直到ACK返回,并且延迟的ACK算法在发生之前增加0.5秒左右。
延迟的ACK是一种赌注。 TCP实现打赌将很快发送数据,并且不必发送单独的ACK。每次实际发送延迟的ACK时,该投注都会丢失。 TCP规范允许实现每次丢失该赌注而不关闭延迟的ACK。恰当地,延迟的ACK应当仅在可能已经捎带的一些不必要的ACK已经连续发送时才开启,并且任何时候实际发送延迟的ACK,应该再次关闭延迟的ACK。应该有一个反击。
不幸的是,在1986年我退出网络之后,延迟的ACK进入了,而这从未修复过。现在为时已晚。
John Nagle
答案 1 :(得分:1)
Nagle的算法应该减少 small 数据包的数量(例如,因此它不会为您通过慢速链接键入telnet的每个字符发送单个数据包)。如果它可以发送一个完整的数据包,它应该发送一个完整的数据包。它没有违反RFC 1122 section 4.2.3.4中的说明:
如果存在未确认的数据(即
SND.NXT > SND.UNA
),则发送TCP将缓冲所有用户 数据(不管PSH位),直到 未完成的数据已被确认或直到 TCP可以发送一个完整的段(Eff.snd.MSS
字节;见4.2.2.6)。
延迟ACK减少了反向发送的数据包数量,但RFC 1122中的描述为实现留下了很多:
TCP应该实现延迟的ACK,但ACK不应该 被过度推迟;特别是延迟必须 小于0.5秒,并在一个全尺寸的流 那里的段应该至少每秒都是一个ACK 段。
请注意,当您发送“批量数据”时,接收器不是!如果它立即发送ACK,它们都是小包,这可能会产生很多开销。
答案 2 :(得分:0)
通过套接字选项关闭Nagle。 Nagle和Delayed ack都默认设置。 Nagle会延迟传输,除非形成完整的数据包或管道中有未包装的数据,因此,它会影响小数据包的应用程序限制流的性能。
取决于发送模式
如果接收方已经有一个未经处理的数据包,这1500字节就会产生一个确认。然而,如果没有先前接收的数据并且接收器没有使用快速确认,则发送ack将被延迟一段时间(例如200ms)或者除非接收到下一个分组。
3号将有所帮助。