关于 nagle 与延迟确认的问题

fus*_*ren 4 networking tcp

我读了在线延迟 ack 结合 Nagle 算法可能存在性能问题。但据我了解,Nagle 算法是延迟确认。如果它们不一样,有什么区别?

小智 9

它们不是一回事,但以某种方式相关,当一起使用时可能会出现一些陷阱和问题。

延迟确认

延迟 ACK 可以看作是在接收端实现的东西。对于延迟 ACK,ACK 不会立即发送,而是会延迟一段时间(通常为 200 毫秒)发送,希望它需要发送的 ACK 可以与本地应用程序希望在另一个方向发送的某些数据组合或“捎带” .

延迟的 ACK 使应用程序有机会更新窗口并可能立即发送响应。特别是在字符模式远程登录的情况下,延迟的 ACK 可以将服务器发送的段数减少 3 倍(ACK、窗口更新和回显字符都组合在一个段中)。

此外,在一些大型多用户主机上,延迟 ACK 可以通过减少要处理的数据包总数来大大减少协议处理开销。然而,ACK 上的过度延迟会干扰往返时间和数据包“计时”算法。RFC1122

延迟 ACK 用于避免这些情况:

Client              Server
  |                   |
  |----- Request ---->|
  |                   |
  |<------ ACK -------|
  |                   |
  |<---- Response ----|
  |                   |
  |------- ACK ------>|
Run Code Online (Sandbox Code Playgroud)

对于延迟 ACK,TCP 将在单个段中发送请求 ACK 和响应。

Client              Server
  |                   |
  |----- Request ---->|
  |                   |
  |<-- Response/ACK---|
  |                   |
  |------- ACK ------>|
Run Code Online (Sandbox Code Playgroud)

John Nagle 在此论坛中提到

延迟 ACK 押注另一端几乎立即回复您刚刚发送的内容。除了一些 RPC 协议,这是不可能的。所以ACK延迟机制输掉了赌注,一遍又一遍,延迟ACK,等待可以搭载ACK的数据包,没有得到它,然后发送ACK,延迟。

纳格尔算法

Nagle 算法可以看作是在发送端实现的某种东西,以提高尝试始终发送全尺寸 TCP 数据包的效率。

摘自 TCP/IP 插图(第 1 卷):W. Richard Stevens 的协议

Nagle 算法说,当 TCP 连接有尚未确认的未完成数据时,在所有未完成数据都得到确认之前,不能发送小段(那些小于 SMSS 的数据段)。相反,当确认到达时,TCP 收集少量数据并在单个段中发送。此过程有效地强制 TCP 进入停止等待行为,它停止发送,直到收到任何未完成数据的 ACK。

实际上,正如 John Nagle 在本论坛中提到的。

如果关闭 Nagle 算法,然后快速向套接字发送单个字节,则每个字节将作为单独的数据包发出。这可以将流量增加一两个数量级,而吞吐量相应地下降。

延迟 ACK 和 Nagle 算法交互

延迟 ACK 和 Nagle 算法交互在TCP/IP 插图(第 1 卷)中描述:W. Richard Stevens 的协议

考虑一个使用延迟 ACK 的客户端向服务器发送请求,而服务器响应的数据量并不完全适合单个数据包。

Nagle 算法与延迟 ACK 之间的交互

在这里,我们看到客户端在收到来自服务器的两个数据包后,保留了一个 ACK​​,希望可以捎带发往服务器的额外数据。一般情况下,TCP 需要为两个接收到的数据包提供 ACK,只有当它们是全尺寸时,它们才在这里。在服务器端,由于 Nagle 算法正在运行,在返回 ACK 之前不允许向客户端发送额外的数据包,因为最多允许一个“小”数据包未完成。延迟 ACK 和 Nagle 算法的组合导致一种形式的死锁(每一方都在等待另一方)。

您还可以在Stuart Cheshire 的这篇论文中阅读 Nagle's Algorithm 和 Delayed ACK 之间的交互引起的问题。