概念:

Nagle算法是根据创建者John Nagle命名。该算法用于对缓冲区内的一定数量的消息进行自动连接。它的作用是减少必要发送封包的数量(小封包).,以提高网络应用程序的利用率。

关于小封包问题的解决方法:当某一应用程序每次只发送一字节或者很少数量的数据时,每次包的大小就是包头40字节+payload,这种过载情况,就会造成封包丢失,网络过度拥挤。而Nagle是怎么做的呢?

Nagle算法的规则:  

1:如果包长度达到MSS,则允许发送;

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

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

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

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

这里MSS是指为了尽可能的利用网络带宽,tcp希望尽可能的发送足够大的数据,这个mss就是最大报文段长度.

nagle算法只允许一个未被ACK的包存在在网络,不管这个包的大小,但是如果ACK回复的快的话,Nagle并没有拼接数据包,网络利用率还是没有提高。 其实Nagle只完成了一半的任务,如果接收端不通告缓冲区很小增长,不通知小窗口,除非有了显著的增长(增长为完全大小的段MSS或大于最大窗口的一半)。

nagle的这种减少大量小包的发送避免了糊涂窗口综合症,为什么说糊涂呢?不管接收到多少数据,都会通告自己的接收窗口大小。能不糊涂吗?

    防止这种糊涂窗口综合症,可以不发送小窗口报告,还有一种机制是延迟ACK。只要延迟ACK,发送端没有收到数据的ACK,发送端是不会发送数据的。但是也带来了延迟.....

    关于延迟ACK与nagle本身的诸多问题,可以参考:http://dog250.blog.51cto.com/2466061/1377408

TCP_NODELAY 选项

默认情况下,发送数据采用了Nagle算法,如果要禁用就调用setsockeopt函数传入TCP_NODELAY