Nagle算法(转)

来源:互联网 发布:淘宝开店代销怎么做 编辑:程序博客网 时间:2024/06/14 17:59


1、Nagle算法作用

        TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

    Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到

2. Nagle算法的规则

1)如果包长度达到MSS(MSS是最大分段大小Maxitum Segment Size ,MTU是最大传输单元Maxitum Transmission Unit),则允许发送;
2)如果该包含有FIN,则允许发送;
3)设置了TCP_NODELAY选项,则允许发送;
4)未设置TCP_CORK选项时,若所有发出去的包均被确认,或所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送。
   对于规则4),就是说一个TCP连接上最多只能有一个未被确认的小数据包,在该分组的确认到达之前,不能发送其他的小数据包。如果某个小分组的确认被延迟了,那么后续小分组的发送就会相应的延迟。也就是说延迟确认影响的并不只是被延迟确认的那个数据包,而是后续所有的应答包。

我的理解:当使用Nagle算法时,如果包的长度等于MSS,则无论之前发送的包是否已经被确认了,都会直接发送,否则等待上一个包确认(在规定时间之内,超过规定时间也会发送,这个时间一般是200ms)收到之后再发送包(这个包的长度可以小于MSS

3. Nagle算法的门槛

   实际上Nagle算法并不是很复杂,他的主要职责是数据的累积,实际上有个门槛:

1)缓冲区中的字节数达到了一定量

2)等待了一定的时间(一般的Nagle算法都是等待200ms);

3)紧急数据发送

   个门槛的任何一个达到都必须发送数据了。一般情况下,如果数据流量很大,第二个条件是永远不会起作用的,但当发送小的数据包时,第二个门槛就发挥作用了,防止数据被无限的缓存在缓冲区不是好事情哦。 

4. Nagle算法的选项配置

   TCP_NODELAY和TCP_CORK都是禁用Nagle算法,只不过NODELAY完全关闭而TCP_CORK完全由自己决定发送时机。Linux文档上说两者不要同时设置

4.1、TCP_NODELAY 选项

   默认情况下, 发送数据采用Nagle 算法. Nagle 算法是指发送方发送的数据不会立即发出,而是先放在缓冲区, 等缓存区满了再发出. 发送完一批数据后, 会等待接收方对这批数据的回应,然后再发送下一批数据 

   Nagle 算法适用于发送方需要发送大批量数据, 并且接收方会及时作出回应的场合, 这种算法通过减少传输数据的次数来提高通信效率

   如果发送方持续地发送小批量的数据, 并且接收方不一定会立即发送响应数据, 那么Nagle算法会使发送方运行很慢

4.2 TCP_CORK选项

   TCP链接的过程中,默认开启Nagle算法,进行小包发送的优化。优化网络传输,兼顾网络延时和网络拥塞。这个时候可以置位TCP_NODELAY关闭Nagle算法,有数据包的话直接发送保证网络时效性。

   在进行大量数据发送的时候可以置位TCP_CORK关闭Nagle算法保证网络利用性。尽可能的进行数据的组包,以最大mtu传输,如果发送的数据包大小过小则如果在0.6~0.8S范围内都没能组装成一个MTU时,直接发送。如果发送的数据包大小足够间隔在0.45内时,每次组装一个MTU进行发送。如果间隔大于0.4~0.8S则,每过来一个数据包就直接发送。

   Nagle组织包的长度是由系统决定的,有时候我们知道我们会每个1分钟产生1字节,共1000字节。如果完全由Nagle算法来发送的话,可能还是会1字节1字节发送[这是一种极端情况,假设返回ACK时间不是很长]。这个时候首先设置TCP_CORK能够阻塞住TCP[尽量阻塞住],等我们write完1000字节之后,取消TCP_CORK,这个时候就能够将1000字节一次发出

4.3、TCP_CORK选项与TCP_NODELAY比较      

1)打开TCP_NODELAY选项,则意味着无论数据包是多么的小,都立即发送(不考虑拥塞窗口)。
2)如果将TCP连接比喻为一个管道,那TCP_CORK选项的作用就像一个塞子。            

   设置TCP_CORK选项,就是用塞子塞住管道,而取消TCP_CORK选项,就是将塞子拔掉。            

   当TCP_CORK选项被设置时,TCP链接不会发送任何的小包,即只有当数据量达到MSS时,才会被发送

   一般当数据传输完成时,通常需要取消该选项,以防被塞住,这样才可以让不够MSS大小的包能及时发出去。


我的理解:当TCP_CORK被设置时,TCP连接不会发送小包,只要当组装的包达到MSS时才会发送或则超时之后也会。还有就是取消TCP_CORK之后也会发送。

目前了解,这里面还涉及到延迟ACK,这个以后再学习

延迟ACK一般在40ms,超过这个时间就会发送这个ACK






0 0