我知道他们两个都破坏了奈格尔的算法。
我什么时候应该/不应该使用它们中的每一个?
这是一种优化,就像任何优化一样:
基本上,这样做的目的是为了避免发送几个框架,其中一个框架可以使用 sendfile ()和它的朋友。
例如,在 Web 服务器中,你发送头文件后面跟着文件内容,头文件将在内存中组装,然后文件将由内核直接发送。TCP _ CORK 允许在一个帧中发送头文件和文件的开头,即使使用 TCP _ NODELAY 也是如此,否则会导致第一个块立即发送出去。
TCP _ CORK 与 TCP _ NODELAY 相反,前者强制数据包累积延迟,后者禁用它。
首先,它们不会同时禁用 Nagle 的算法。
Nagle 的算法是为了减少有线网络中更多的小型网络数据包。该算法是: 如果数据小于一个限制(通常是 MSS) ,等待,直到收到应答以前发送的数据包,并在同一时间积累数据从用户。然后发送累积的数据。
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 将被给予更多的优先权。
参考:
TCP_NODELAY
用于禁用 Nagle 的算法,以改进 TCP/IP 网络,并通过等待收到对先前发送的数据的确认后再发送累积的数据包来减少数据包的数量。
//摘自 tcp (7)手册:
TCP_CORK (或 FreeBSD 中的 TCP_NOPUSH)
TCP_CORK
TCP_NOPUSH
如果设置了,不要发送部分帧。当再次清除该选项时,将发送所有排队的部分帧。这对于调用 sendfile(2)之前的前置标头或吞吐量优化非常有用。根据目前的实现,有一个 最多200毫秒的时间输出是由 TCP_CORK塞。如果达到这个上限,那么队列数据将自动传输.自从 Linux 2.5.71以来,这个选项只能与 TCP_NODELAY组合使用。此选项不应用于旨在可移植的代码中。
sendfile(2)