什么时候应该使用TCP_NODELAY和TCP_CORK?

时间:2010-09-21 14:24:47

标签: linux sockets tcp

据我所知,他们都禁用了Nagle的算法。

我应该/不应该在何时使用它们?

4 个答案:

答案 0 :(得分:67)

首先,并非他们都禁用了Nagle的算法。

Nagle的算法用于减少线路中更多的小型网络数据包。算法是:如果数据小于限制(通常是MSS),则等待直到接收先前发送的数据包的ACK并且同时累积来自用户的数据。然后发送累积的数据。

if [ data > MSS ]
    send(data)
else
    wait until ACK for previously sent data and accumulate data in send buffer (data)
    And after receiving the ACK send(data)

这将有助于telnet等应用程序。然而,等待ACK可能在发送流数据时增加等待时间。此外,如果接收器实现'延迟ACK策略',它将导致临时死锁情况。在这种情况下,禁用Nagle算法是一个更好的选择。

因此TCP_NODELAY用于禁用Nagle的算法。

TCP_CORK积极地积累数据。如果在套接字中启用了TCP_CORK,则在缓冲区填充到固定限制之前,它不会发送数据。与Nagle的算法类似,它也会累积来自用户的数据,但直到缓冲区填充到固定限制,直到收到ACK。这在发送多个数据块时非常有用。但是在使用TCP_CORK时你必须要小心。

直到2.6内核,这两个选项都是互斥的。但是在后来的内核中,它们都可以一起存在。在这种情况下,TCP_CORK将获得更多的偏好。

价:

答案 1 :(得分:19)

<强> TCP_NODELAY

用于禁用nagle的算法来改进tcp / ip网络,并通过等待收到先前发送的数据的确认来发送累积的数据包来减少数据包的数量。

//来自tcp(7)手册:

TCP_CORK(或FreeBSD中的TCP_NOPUSH)

如果设置,请不要发送部分帧。再次清除该选项时,将发送所有排队的部分帧。这对于在调用sendfile(2)之前预先添加标头或用于吞吐量优化非常有用。正如目前实施的那样,TCP_CORK的输出时间上限为200毫秒。 如果达到此上限,则会自动传输排队的数据。自Linux 2.5.71起,此选项只能与TCP_NODELAY结合使用。此选项不应用于可移植的代码中。

答案 2 :(得分:6)

这是一种优化,就像任何优化一样:

  1. 不要使用
  2. 等到性能出现问题,然后确定套接字延迟肯定是它的原因,并且测试证明这肯定会解决它,并且这是修复它的最简单方法,做到这一点。
  3. 基本上,目标是避免使用sendfile()及其朋友发送可以使用单个帧的几个帧。

    例如,在Web服务器中,您发送标题后跟文件内容,标题将在内存中汇编,然后文件将由内核直接发送。 TCP_CORK允许您在单个帧中发送文件的头部和开头,即使使用TCP_NODELAY,否则会导致第一个块立即发送出去。

答案 3 :(得分:0)

TCP_CORK与TCP_NODELAY相反。前者强制数据包累积延迟;后者禁用它。