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

我明白,他们都禁用Nagle的algorithm。

什么时候应该/不应该使用他们中的每一个?

首先,它们都不能禁用Nagle的algorithm。

Nagle的algorithm是为了减less更多数量的小型networking数据包。 该algorithm是:如果数据小于限制(通常是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可能增加发送stream数据时的等待时间。 另外,如果接收方执行“延迟的ACK策略”,则会导致暂时的死锁情况。 在这种情况下,禁用Naglealgorithm是更好的select。

所以TCP_NODELAY用于禁用Nagle的algorithm。

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

在2.6内核之前,这两个选项是相互排斥的。 但在后来的内核中,它们都可以一起存在。 在这种情况下,TCP_CORK将会被赋予更多的优先权。

参考:

TCP_NODELAY

用来禁用naglealgorithm来改善tcp / ipnetworking,并通过等待收到先前发送的数据的确认来发送累积的数据包来减less数据包的数量。

//从tcp(7)手册:

TCP_CORK(或FreeBSD中的TCP_NOPUSH)

如果设置,不要发送部分帧。 当选项被再次清除时,所有排队的部分帧被发送。 这在调用sendfile(2)之前预先确定标题或用于吞吐量优化时很有用。 按照目前的实施情况,TCP_CORK的输出时间上限为200毫秒。 如果达到这个上限,排队的数据会自动发送 。 从Linux 2.5.71开始,此选项只能与TCP_NODELAY结合使用。 这个选项不应该用在可移植的代码中。

这是一个优化,所以像任何优化:

  1. 不要使用它
  2. 等到性能成为问题,然后确定套接字延迟肯定是它的原因,testingcertificate这一定会修复它,这是修复它的最简单的方法,这样做。

基本上,目的是避免发送多个帧,其中可以使用单个帧,sendfile()及其朋友。

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

TCP_CORK与TCP_NODELAY相反。 前者强制分组累积延迟; 后者禁用它。