设置TCP_QUICKACK和TCP_NODELAY

don*_*lmg 20 c sockets linux tcp

如果你在套接字上的每个调用上设置了TCP_QUICKACK设置,之前已经设置了TCP_NODELAY,那么QUICKACK选项是否会覆盖NODELAY调用?

在连接上:

int i = 1;
setsockopt( iSock, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof(i));
Run Code Online (Sandbox Code Playgroud)

每次写:

int i = 1;
setsockopt( iSock, IPPROTO_TCP, TCP_QUICKACK, (void *)&i, sizeof(i));
Run Code Online (Sandbox Code Playgroud)

对TCP_QUODACK的调用是否会使先前对TCP_NODELAY的调用无效?

Fei*_*Fei 24

这两个选项之间没有直接的关系,它们只是出于不同的目的.

TCP_NODELAY旨在禁用/启用段缓冲,以便尽快将数据发送到对等方,因此通常用于提高网络利用率.TCP_QUICKACK用于尽早发送确认而不是在某些协议级别交换下延迟,并且它不稳定/永久,后续TCP事务(可能发生在幕后)可以忽略此选项,具体取决于实际协议级别处理或任何实际用户设置和堆栈行为之间的分歧.

注意 TCP_NODELAY是可移植的而TCP_QUICKACK不是(仅适用于Linux 2.4.4+).


rof*_*rol 10

使用TCP_QUICKACK,而不是TCP_NODELAY

打开TCP_NODELAY具有类似的效果,但可以使小写入的吞吐量更差.如果你写一个循环只发送几个字节(最坏的情况,一个字节)到一个带有"write()"的套接字,并且使用TCP_NODELAY禁用Nagle算法,则每次写入变成一个IP数据包.这会将流量增加40倍,每个有效负载使用IP和TCP标头.如果您有一个正在运行的数据包,Tinygram预防将不允许您发送第二个数据包,除非您有足够的数据来填充最大尺寸的数据包.它累计一个往返时间的字节,然后发送队列中的所有内容.这几乎总是你想要的.如果设置了TCP_NODELAY,则需要更加了解缓冲和刷新问题.对于批量单向传输而言,这些都不重要,这在今天是大多数HTTP.(我从来没有看过这对SSL握手的影响,它可能很重要.)短版本:设置TCP_QUICKACK.如果您发现导致情况恶化的情况,请告诉我.约翰纳格尔

https://news.ycombinator.com/item?id=10608356


zan*_*ngw 6

简短回答

\n
    \n
  • 要禁用 Nagle 的缓冲算法,请使用 TCP_NODELAY 套接字选项。
  • \n
  • 要禁用延迟 ACK,请使用 TCP_QUICKACK 套接字选项。
  • \n
\n

细节

\n
    \n
  • 内格尔算法

    \n
      \n
    • Nagle 算法以其创建者 John Nagle 命名,是一种通过减少网络上发送的小数据包数量来提高 TCP 效率的机制。
    • \n
    • 目标是在应用程序向套接字传送数据的速度相当缓慢时,防止节点传输许多小数据包。
    • \n
    • 如果某个进程导致传输许多小数据包,则可能会造成过度的网络拥塞。如果数据包的有效负载小于 TCP 标头数据,则尤其如此。
    • \n
    \n
  • \n
  • 延迟确认

    \n
      \n
    • TCP 延迟确认或延迟 ACK 是某些 TCP 实现使用的另一种技术,旨在提高网络性能并减少拥塞。
    • \n
    • 延迟 ACK 的发明是为了减少确认分段所需的 ACK 数量并减少协议开销。
    • \n
    • 延迟 ACK 意味着 TCP 不会立即确认每个收到的 TCP 段。多个 ACK​​ 响应可以组合在一起形成单个响应,从而减少协议开销。
    • \n
    \n
  • \n
  • Nagle 算法和延迟 ACK 在 TCP/IP 网络中不能很好地协同工作

    \n
      \n
    • 如果可以的话,延迟 ACK 会尝试为每个段发送更多数据。但 Nagle 算法的一部分依赖于 ACK 来发送数据。

      \n
    • \n
    • Nagle 的算法和延迟的 ACK 一起产生了一个问题,因为延迟的 ACK 正在等待发送 ACK,而 Nagle 的算法正在等待接收 ACK

      \n
    • \n
    • 样本

      \n
      client: hi! Here\xe2\x80\x99s the first packet\nserver: <silence, waiting for the second packet, well I\xe2\x80\x99ll ack eventually>\nclient: <silence, well I\xe2\x80\x99m waiting for an ACK, maybe there\xe2\x80\x99s network congestion>\nserver: Ok I am bored. Here\xe2\x80\x99s an ack\nclient: Great, here\xe2\x80\x99s the second packet!\nserver: Sweet. we\xe2\x80\x99re done here\n
      Run Code Online (Sandbox Code Playgroud)\n
        \n
      • 客户端这样做是因为 Nagle\xe2\x80\x99s 算法,而服务器这样做是因为延迟的 ACK。
      • \n
      \n
    • \n
    \n
  • \n
  • 如何解决 Nagle 算法和延迟 ACK 引起的问题

    \n
      \n
    • 启用 TCP_NODELAY 通过服务器上的全局套接字选项禁用 Nagle 算法
    • \n
    • 在代理服务器和负载均衡器上进行配置文件调整:如果您运行的应用程序或环境有时具有高度交互的流量和繁琐的协议,则这一点尤其重要。通过在负载均衡器级别动态切换 Nagle 算法和 TCP_NODELAY,您甚至可以保持高度异构的流量混合以最佳状态运行。
    • \n
    • 减少服务器和负载均衡器上的延迟 ACK 计时器。有时,这种优化是在应用程序级别的软件中处理的,但当情况并非如此时,您仍然可以在服务器或负载均衡器级别动态管理 ACK 计时器。
    • \n
    • 当您进行这些更改时,请仔细观察您的网络流量,并了解每个调整如何影响拥塞。
    • \n
    \n
  • \n
\n

欲了解更多详细信息,请参阅

\n


Mat*_*ats 5

TCP_QUICKACKTCP_NODELAY影响TCP中的不同操作。手册tcp(7)页描述了 TCP 的哪些套接字选项相互干扰,例如TCP_CORKTCP_NODELAY