根据这篇 Socket FAQ 文章,Nagle 的算法是许多算法之一,它可以导致一堆数据位于 TCP 缓冲区中而不会发生在网络上。Nagle 算法的延迟最高可达 200 毫秒。
出于某种原因,Nagle 的算法可以完全关闭,但不能只刷新一次。这对我来说真的很令人费解。为什么没有办法说“就这一次,不要等待更多数据。就像Nagle的200ms到了一样。”
这难道不是很有意义,并且在根本没有 Nagle、一直 Nagle 和从头实现自己的协议之间取得很好的平衡吗?
根据这篇 Socket FAQ 文章,Nagle 的算法是许多算法之一,它可以导致一堆数据位于 TCP 缓冲区中而不会发生在网络上。Nagle 算法的延迟最高可达 200 毫秒。
出于某种原因,Nagle 的算法可以完全关闭,但不能只刷新一次。这对我来说真的很令人费解。为什么没有办法说“就这一次,不要等待更多数据。就像Nagle的200ms到了一样。”
这难道不是很有意义,并且在根本没有 Nagle、一直 Nagle 和从头实现自己的协议之间取得很好的平衡吗?
好问题。我想没有人真正需要它,或者他们绕过它。如果我没记错TCP_NODELAY
的话,启用会立即推送数据。然后你可以禁用它。
当然,这是以两次系统调用“刷新”为代价的。你可以做什么:send(2)
,在 Unix 实现上有一个flags
论点。您可以实现自己的标志,例如:(MSG_JUSTPUSHIT
好吧,也许是另一个名称)并在tcp_output
.
在 Nagle 算法引入的延迟是一个问题的性能敏感型应用程序中,通常更容易完全禁用 Nagle 算法并通过使用分散/收集 IO(例如writev()
,或通过在需要时在软件中实现缓冲)在软件中模拟其批处理. 作为额外的好处,这样做可以减少一些系统调用开销。
或者,您可以打开两个单独的套接字并在其中一个上禁用 Nagling。请记住,在一个套接字上发送的数据不一定会与另一个套接字同步。