TCP_NODELAY, TCP_CORK, Nagle TCP/IP之 Nagle 算法与40ms延迟提到了Nagle 算法。这样虽然提高了网络吞吐量, 但是实时性却降低了, 在一些交互性很强的应用程序来说是不允许的, 使用 TCP_NODELAY 选项可以禁止 Nagle 算法。 禁止Nagle 后应用程序向内核递交的每个数据包都会立即发送出去。 但是禁止 Nagle, 网络传输仍然受到 TCP 确认延迟机制的影响。
TCP_CORK CORK 意思是塞子, TCP中的 CORK 意思是将连接塞住, 使得数据先不发出去, 等到拔去塞子后再发出去。 设置该选项后, 内核会尽力把小数据包拼接成一个大的数据包 (一个MTU) 再发送出去, 一定时间后, 内核仍然没有组合成一个 MTU 时也必须发送现有的数据。 然而, TCP_CORK 的实现可能并不像你想象的那么完美, CORK 并不会将连接完全塞住。内核其实并不知道应用层到底什么时候会发送第二批数据用于和第一批数据拼接以达到 MTU 的大小, 因此内核会给出一个时间限制, 在该时间内没有拼接成一个大包 (努力接近 MTU) 的话, 内核就会无条件发送。 也就是说若应用层程序发送小包数据的间隔不够短时, TCP_CORK 就没有一点作用, 反而失去了数据的实时性 (每个小包数据都会延时一定时间再发送,这个时间超过了内核的时间限制) 。
Nagle 算法和 CORK 算法非常类似, 但是它们的着眼点不一样, Nagle 算法主要避免网络因为太多的小包 (协议头的比例非常之大) 而拥塞, 而 CORK 算法则是为了提高网络的利用率,使得总体上协议头占用的比例尽可能的小。如此看来这二者在避免发送小包上是一致的,在用户控制的层面上,Nagle算法完全不受用户socket的控制,你只能简单的设置TCP_NODELAY而禁用它,CORK算法同样也是通过设置或者清除TCP_CORK使能或者禁用之,然而Nagle算法关心的是网络拥塞问题,只要所有的ACK回来则发包,而CORK算法却可以关心内容,在前后数据包发送间隔很短的前提下 (很重要,否则内核会帮你将分散的包发出) ,即使你是分散发送多个小数据包,你也可以通过使能CORK算法将这些内容拼接在一个包内,如果此时用Nagle算法的话,则可能做不到这一点。
Nagle 算法 根据创建者John Nagle命名。该算法用于对缓冲区内的一定数量的消息进行自动连接。该处理过程(称为 Nagling ), 通过减少必须发送的封包的数量, 提高了网络应用 程序系统的效率。Nagle算法, 由Ford Aerospace And Communications Corporation Congestion Control in IP/TCPinternetworks(IETF RFC 896)(1984)定义, 最初是用于缓冲 Ford 的私有 TCP/IP 网络拥塞情况, 不过被广泛传播开来。
...