TCP_NODELAY, TCP_CORK, Nagle
Contents
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 网络拥塞情况, 不过被广泛传播开来。
Nagle 的文档定义了一种他称之为小封包问题的解决方法。当某个应用程序每次只产生一字节的数据, 就会导致网络由于这样的小封包而过载 (该情况通 常被称为"发送端 SB 窗口并发症”) , 从而产生该问题。一个源自键盘的单一字符-1字节的数据-可能导致一个41字节的封包被传送, 该封包包含了1字节的有用数据和40字节的头部数据。这种 4000% 过载的情况, 在像 APRANET 这样只有很轻负载的网络中是可以接受的, 但在像 Ford 这样的负载很重的网络中, 可能强制重传, 导致封包丢失, 并且通过过度拥挤交换节点和网关降低了传播速度。 更进一步,当连接被丢弃时,吞吐量可能被降低。
虽然 Nagle 算法用于解决 Ford 网络内产生的问题, 但同样的问题也出现在 APRANet。 通过网络, Nagling 被广泛实现, 包括 internet, 并且产生了巨大的效用-虽然某些时候在高交互性环境如一些 C/S 情况下不希望进行该处理。在这种情况下,可以通过 TCP_NODELAY socket 选项关闭 Nagling。
注: Nagle 虽然解决了小封包问题, 但也导致了较高的不可预测的延迟, 同时降低了吞吐量。
TCP_CORK
TCP 链接的过程中, 默认开启 Nagle 算法, 进行小包发送的优化。优化网络传输, 兼顾网络延时和网络拥塞。这个时候可以置位 TCP_NODELAY 关闭 Nagle 算法, 有数据包的话直接发送保证网络时效性。在进行大量数据发送的时候可以置位 TCP_CORK 关闭 Nagle 算法保证网络利用性。尽可能的进行数据的组包, 以最大 mtu 传输, 如果发送的数据包大小过小则如果在0.6 ~ 0.8S
范围内都没能组装成一个 MTU 时, 直接发送。如果发送的数据包大小足够间隔在0.45内时,每次组装一个MTU进行发送。如果间隔大于0.4 ~ 0.8S
则,每过来一个数据包就直接发送。
实测打开 TCP_CORK 选项会使响应出现 1 至 2 秒的延迟。 比上面说的要长一些。
TCP_NODELAY
如果发送方持续地发送小批量的数据, 并且接收方不一定会立即发送响应数据, 那么Nagle 算法会使发送方运行很慢. 对于GUI 程序, 如网络游戏程序(服务器需要实时跟踪客户端鼠标的移动), 这个问题尤其突出. 客户端鼠标位置改动的信息需要实时发送到服务器上, 由于Nagle 算法采用缓冲, 大大减低了实时响应速度, 导致客户程序运行很慢.
TCP_NODELAY 和 TCP_CORK
- 历史上TCP是每发送一次包等待一个ACK然后下一个
- 但是在一些交互式应用下比如 Telnet, 结果就是我们每按一次键就会发送一个packet. 每一个字符配一个 TCP 头效率不高, 那个 Nagle 算法出来了。 发送方法送数据 A 时然后再等待接受方的 ACK 时, 积累本地收集到的所有TCP数据包然后一次性发送。
- 很明显 Nagle 算法不利于交互式情景, 而现代应用下面还是存在交互式应用的,所以有时候我们需要关闭 Nagle那么可以设置 TCP_NODELAY
- Nagle 组织包的长度是由系统决定的, 有时候我们知道我们会产生大量的数据。 这个时候首先设置 TCP_CORK 能够阻塞住 TCP [尽量阻塞住], 以尽量减少发送的数据包数量。
TCP_NODELAY和TCP_CORK都是禁用Nagle算法,但两者不能同时设置。
相关文章
Linux无法产生core dump的原因
一、要保证存放Coredump的目录存在且进程对该目录有写权限。存放Core …
HTTP 协议缓存机制详解
浏览器第一次请求流程图: 浏览器再次请求时: Expires策略: Expires是W …
Chrome 处理长连接时遇到的一些问题
最近在原有的 Webit 基础上开发了一个基于 HTTP 协议和 RESTful …
automake, autoconf 使用详解
文章转自: http://www.laruence.com/2009/11/18 …
Keep Alive 对 HTTPS 性能的巨大影响
最近为 Webit 添加了 HTTPS 支持。为了了解 HTTPS 下的性能,我 …
http://www.cnblogs.com/jiayayao/p/6217744.html
http://www.cnblogs.com/jiayayao/p/6217802.html
http://www.cnblogs.com/maowang1991/archive/2013/04/16/3024518.html
Author -
LastMod 2017-09-21