关于 tcp 的 nodelay

2015-12-26 21:33:08 +08:00
 sujin190

网上很多资料都说设置 tcp nodelay 会关闭 Nagle 算法,写入缓冲区的数据会立即发送,那么这个选项是完全关闭一定不再就行数据连接呢,还是在快速发送大量数据,缓冲去数据在无法立即发送时还是会进行数据连接呢?比如我们每次发送 10 字节,一定是每个 tcp 包都是 10 字节负载么?

2350 次点击
所在节点    问与答
6 条回复
ryd994
2015-12-27 01:31:49 +08:00
在缓冲区一直有很多数据的情况下开关没有区别
区别只在缓冲有一丁点数据,远小于 mtu 的时候
sujin190
2015-12-27 14:12:28 +08:00
@ryd994 我想也应该是这样,否则就不合理了,只是没有地方对这个有说明,想求证一下
redsonic
2015-12-27 18:27:21 +08:00
"关闭 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 的影响,实际发包的时机。
sujin190
2015-12-27 22:43:52 +08:00
@redsonic 感谢解答,内核什么的估计还看不动,以前都没注意过,最近在观察 tcp 发包过程忽然想到这个问题
ryd994
2015-12-28 01:49:50 +08:00
@redsonic 你说的对端 ACK 和剩余数据,那个应该属于 window size 吧?和 nagle 有什么关系?
redsonic
2015-12-28 02:05:07 +08:00
@ryd994 ACK 和 window 有关系,属于 TCP 拥塞管理的部分,但也和 nagle 有关系,摘自 TCP/IP 详解卷 1 ”该算法要求一个 TCP 连接上最多只有一个未被确认的未完成小分组,在该分组的确认到达之前不能发送其他的小分组。相反, TCP 收集这些少量的分组,并在确认到来时以一个分组的方式发出去“。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/246358

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX