Nagle 算法尽量减少小分组出现在网络上,而 TCP_CORK 是完全避免小分组出现在网络上。该选项是在 Linux 2.2 才引入的。
cork 这个单词,意为“塞子”,我们把 TCP 发送缓冲区想象成一个水池,而 cork 的作用就是把这个水池的出口堵住,直到下面的事情发生才会拔掉塞子,发送数据:
- 水池满了
- 达到一定的大小,比如超过 MSS 了
- 一段时间都没有水进来(比如 200ms)
- 遇到 FIN 了
- 会不会还有其它情况?
1. 程序路径
代码托管在 gitos 上,请使用下面的命令获取:
git clone https://git.oschina.net/ivan_allen/unp.git
如果你已经 clone 过这个代码了,请使用 git pull
更新一下。本节程序所使用的程序路径是 unp/program/options/opt
。
2. 实验
实验中我们设置 TCP_CORK 选项,然后发送小分组,观察 tcpdump 的输出。
- flower 上启动服务器
$ ./opt -s -h flower --slowread 4096
- sun 上启动客户端,打开 TCP_CORK 选项
// 打开 TCP_CORD,一次 write 1 字节 $ ./opt -h flower --cork --writesize 1
图1 开启 TCP_CORK 选项,完全避免发送小分组
我们看到 11 字节数据被发送出去,是因为超时,尽管 11 字节的分组仍然是小分组。
为了方便你对照它与 Nagle 的区别,我把上一篇文章的结果拿来进行对比。如图 2.
图2 开启 Nagle 算法
3. TCP_CORK 与 TCP_NODELAY
这两个选项完全是相反的作用,所以使用的时候,二者不能同时开启。但是从 Linux 2.5.71 内核开始,却可以同时打开这两个选项……想看结果吗?见图 3.
图3 同时打开 TCP_CORK 与 TCP_NODELAY
结果显示的是按照 TCP_CORK 算法来的。。。
man 手册推荐:如果你的代码要求可移植,就不应该使用 TCP_CORK 选项。
4. 总结
- 掌握 TCP_CORK 选项的作用
- 知道 TCP_NODELAY、TCP_CORK 的区别
- 知道 cork 与 nagle 的区别