网上很多资料都说设置 tcp nodelay 会关闭 Nagle 算法,写入缓冲区的数据会立即发送,那么这个选项是完全关闭一定不再就行数据连接呢,还是在快速发送大量数据,缓冲去数据在无法立即发送时还是会进行数据连接呢?比如我们每次发送 10 字节,一定是每个 tcp 包都是 10 字节负载么?
1
ryd994 2015-12-27 01:31:49 +08:00 via Android
在缓冲区一直有很多数据的情况下开关没有区别
区别只在缓冲有一丁点数据,远小于 mtu 的时候 |
3
redsonic 2015-12-27 18:27:21 +08:00 1
"关闭 Nagle 算法,写入缓冲区的数据会立即发送" 这句话是对的。接下来的一个问句看不太明白。
最后一个问句”比如我们每次发送 10 字节,一定是每个 tcp 包都是 10 字节负载么?“ 这个不对:和开不开 TCP_NODELAY 没关系。 TCP 是面向流的,写入缓冲区相当于把包裹交给快递员,至于快递公司的飞机什么时候飞,飞机载荷多少你是不知道的。加了 TCP_NODELAY 相当于加急件,塞到即将起飞的飞机上,但这架飞机上肯定不止这一件货物。 Nagle 算法除了和缓冲区有关(加急件),还隐藏着和对端的 ACK 交互:如果没有 TCP_NODELAY ,则没有收到对端 ACK 之前,不能发送缓冲区中剩余的数据,类似于 USB2.0 的传输方式。开了 TCP_NODELAY 则可以无视对方 ACK 应答是否已收到(实际上还有很多其他限制),尽可能早点发出缓冲区剩余的数据,类似于 USB3.0 的传输方式(可能是 3.1 ,记不清了)。 想深入了解话可以看看老神书 TCP IP 详解卷 1 。 想了解真实的协议栈里面是怎么处理的可以看看内核代码,看了就有收获,很多细节,比如 TSO 对 nodelay 的影响,实际发包的时机。 |