代码改变世界

TCP/IP之Nagle算法与40ms延迟

2016-12-24 16:15  jiayayao  阅读(3330)  评论(0编辑  收藏  举报

  Nagle算法是针对网络上存在的微小分组可能会在广域网上造成拥塞而设计的。该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组确认到达之前不能发送其他的小分组。同时,TCP收集这些少量的分组,并在确认到来时以一个分组发出去。它的设计规则如下:

  (1)如果包长度达到最大报文长度(MSS,Maximum Segment Size),则允许发送;

  (2)如果该包含有FIN,则允许发送;

  (3)设置了TCP_NODELAY选项,则允许发送;

  (4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;

  (5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送。

  与Nagle算法相对应的TCP确认延迟机制(TCP Delayed acknowledge)设计的作用是接收到数据后延迟ACK的发送(40ms),使得TCP协议栈有机会合并多个ACK以提高性能。

  由于有Nagle算法,如果发送端启用了Nagle算法,接收端启用了TCP Delayed Acknowledge。当发送端发起两次写一次读的时候,第一次写,由于TCP没有等待ACK,直接发出去了,而第二次写的时候,第一次写的ACK还没有接收到,从而等待;而接收端有Delayed Acknowledge机制,会等待40ms以提供合并多个ACK的机会。Nagle算法的使用在一些实时性要求比较高的场合,会引起一些问题。比如项目中设计的UI鼠标远程控制远端的机器时,发现远端的鼠标操作很卡顿,这是因为鼠标消息的发送端由于Nagle算法的默认开启,是有延迟的,对相应的socket设置为TCP_NODELAY即可关闭Nagle算法:

setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(flag));