TCP的Nagle算法与ACK延滞算法

作者: wayyyy | 来源:发表于2017-11-09 20:43 被阅读0次
    ACK延滞算法

    TCP协议规定在接受到数据段时需要向对方发送一个确认ACK,但如果只是单纯的发送一个确认ACK,代价会比较高(20字节的IP首部,20字节的TCP首部),最好能附带响应数据一起发送给对方。于是就有了ACK延滞算法。

    该算法使得TCP在接收到数据后不能立即发送ACK,而是等待一段时间,然后才发送ACK。TCP期待在这等待的一小段时间内自身有数据发送回对端,被延滞的ACK就可以由这些数据捎带,从而省掉一个TCP分节。这个时延一般为200ms,也就是说,TCP将以最大200ms的时延等待是否有数据一起发送。

    这里的延迟200ms,不是指的从接受到对方数据到发送ack的最长等待时间差。而是指的内核启动的一个定时器,它每隔200ms就查看下是否有ack要发送。例如:假设定时器在0ms时启动,对方的数据段在185ms时到达,那么ack最迟会在200ms时发送,而不是385ms时发送。

    Nagle算法

    Nagle算法的目的在于减少广域网上小分组的数。

    该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他小分组。相反TCP收集这些少量的分组,并在确认到来时以一个分组的方式发送出去。

    Wikipedia的Nagle算法的伪码实现

    if there is new data to send
    {
        if the window size >= MSS and available data is >= MSS
        {
            send complete MSS segment now
        }
        else
        {
            if there is unconfirmed data still in the pipe
                enqueue data in the buffer until an acknowledge is received
            else
                send data immediately
        }
    }
    

    在套接字选项设置中,可以开启TCP_NODELAY禁用Nagle算法,允许小包发送。

    对于延时敏感型,同时数据传输量比较小的应用,开启TCP_NODELAY选项是一个正确的选择。比如,对于SSH会话,数据传输非常少,但是要求用户的输入能够及时获得返回,有较低的延时。如果开启了Nagle算法,就很可能出现频繁的延时,导致用户体验极差。

    对于关闭TCP_NODELAY,则是应用了Nagle算法。数据只有在写缓存中累积到一定量之后,才会被发送出去,这样明显提高了网络利用率。但是这又不可避免地增加了延时,与TCP 延滞算法结合,这个问题会更加显著。

    • 现在假设发送方A开启Nagle算法, 接收方B采用ACK延滞算法。
      • A 发送一个包给B,N采用ACK延滞算法,暂时不会发送ACK。
      • B 发送第二个包,由于Nagle算法,这个包不会立即发送,会放在发送缓冲区中。假设此时没有确认时延200ms,那么将会发生死锁。A等待B的ACK,才会发送新的数据。B由于ACK延滞,也等不到A的数据。

    相关文章

      网友评论

        本文标题:TCP的Nagle算法与ACK延滞算法

        本文链接:https://www.haomeiwen.com/subject/xhbmmxtx.html