问题
交互数据会产生众多小片报文,过多小分组可能增加网络拥塞的可能。
Nagle算法
Nagle算法规定,一个tcp链接上最多只能有一个未被确认的小分组。
如果ack响应到达前,tcp暂时收集待发数据,等到响应ack到达后使用一个分组将待发数据发送出去。
Nagle算法启动的条件,当一个ack会来之前,就有待发送数据。
1、 不启动nagle,有待发送数据就发送
2、 启动nagle,待发送数据先暂存,等ack回复后集中一片报文发送
上一节流程图中,一个字符发送和字符回显平均时间约为16ms,那么一秒钟少于62个字符,不会出现nagle算法起作用。
如果一秒钟敲击字符过多(超过62字符),或者网络RTT(报文一去一回)过大,那么就有可能启动nagle
Nagle算法启动条件
字符发送周期 < 网络RTT
如下图,这种场景没有ack延迟发送。
这种场景,字符发送需求密集(如上分析超过62个/秒)度大,即不等ack响应的延迟定时器超时就有字节发送,所以抓图中,不存在ack延迟的场景。
![7eb7414d63c8f534c0a278e96c42bdc8.png](https://i-blog.csdnimg.cn/blog_migrate/bca0d44abba7c37ab9ac0b7453e2b2ac.jpeg)
![d10c0b19ad570cca2066de0b3150ac37.png](https://i-blog.csdnimg.cn/blog_migrate/969fab25a6efe6af1470e639b54f445b.jpeg)
报文发送数据和相应分析如下表
![776fd3b0b44ab82e3f54bb07d1a08af8.png](https://i-blog.csdnimg.cn/blog_migrate/427afb239f4d12329931c2b571e72316.jpeg)
关注一下“报文14”和“报文15”,客户端在报文14的ack之前,又发送了报文15,违背了nagle算法?
报文15是对报文13的ack,
注意:
1、 符合nagle算法发送,网络上唯一一个数据被ack后,可以发送累积的待发数据;
2、 有接收数据需要ack,ack报文和累积数据合并发送。
启动nagle算法,并不限制第二条场景发送数据。
Nagle算法的关闭
有些场景需要关闭nagle算法。
比如键盘的功能键会产生多个字符,比如F1、F2等按键,会产生三个字符,这些都是以escape开始的三个字符,当escape发送出去后,对端并不回ack,而是等待后面两个字符,ack超时需要200ms定时器超时,最坏情况下可能达到200ms,这样用户的回显就会有延迟感。所以这种情况下需要关闭nagle算法。
Tcp提供TCP_NODELAY关闭nagle算法。