zoukankan      html  css  js  c++  java
  • TCP的快速重传和快速恢复算法

    TCP除了有重传定时器来保证将丢失的数据重传以外,还有一些辅助算法用来协助完成数据的重传。

    我们认识到在收到一个失序的报文段时, T C P立即需要产生一个 A C K(一个重复的 A C K)。这个重复的 A C K不应该被迟延(tcp需要ack,可是为了效率以及考虑到资源消耗等问题,并不是每发送一个数据都要等待ack,而是尽可能利用窗口机制,积累发送ack的,此处知悉便可)。该重复的 A C K的目的在于让对方知道收到一个失序的报文段,并告诉对方自己希望收到的序号。

    由于我们不知道一个重复的 A C K是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,因此我们等待少量重复的 A C K到来。假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的 A C K之前,只可能产生 1 ~ 2个重复的 A C K。如果一连串收到 3个或3个以上的重复 A C K,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就是快速重传算法。

    简单解释一下为什么接收端接收到3个重复ack就会认定报文丢失而启动快速重传:

    一个报文谈不上顺序,最少两个报文才有顺序的概念,正如字节序一样,utf8以一个字节为编码单位,因此就没有字节序的问题,同样的,仅仅来了一个报文也不能说它对于当前按序的报文来讲是乱序的,只有当第二个报文到来的时候,如果当前按序报文,第一个报文,第二个报文拼不成顺序才能说明后来的这两个报文是乱序的,当然这也是一种权衡的结果,正如三次握手为何是三次一样,即使接收端收到了第三个乱序报文,仍有可能被第四个填充后成为按序报文,没完没了等下去是不行的,必须在发送端接收到确定的,不是很大的数目冗余ack的时候进入快速重传,同时也不能频繁的快速重传,因此就选择了3个冗余ack,当然这个数字是可以配置的。说白了,可以理解为这是考虑各方面性能及消耗而人为设定的一个阈值。

    接下来执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法(在这种情况下没有执行慢启动的原因是由于收到重复的 A C K不仅仅告诉我们一个分组丢失了。由于接收方只有在收到另一个报文段时才会产生重复的 A C K,而该报文段已经离开了网络并进入了接收方的缓存。也就是说,在收发两端之间仍然有流动的数据,而我们不想执行慢启动来突然减少数据流)。

    快速恢复算法实现:
    1) 当收到第3个重复的A C K时,将s s t h re s h设置为当前拥塞窗口 c w n d的一半。重传丢失的报文段。设置c w n ds s t h re s h加上3倍的报文段大小。
    2) 每次收到另一个重复的 A C K时, c w n d增加1个报文段大小并发送 1个分组(如果新的c w n d允许发送) 。
    3) 当下一个确认新数据的 A C K到达时,设置c w n ds s t h re s h(在第1步中设置的值)。这个A C K应该是在进行重传后的一个往返时间内对步骤 1中重传的确认。另外,这个 A C K也应该是对丢失的分组和收到的第 1个重复的A C K之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当前的速率减半。

     

    T C P将忽略I C M P主机不可达的差错并坚持重传 ,而且采用指数退避方法进行重传,减少网络冲突(和保证共享资源的公平性??)。

  • 相关阅读:
    SQL SERVER中一些常见性能问题的总结
    【BZOJ2554】Color 概率神题
    【BZOJ1818】[Cqoi2010]内部白点 扫描线+树状数组
    【BZOJ1879】[Sdoi2009]Bill的挑战 状压DP
    【BZOJ2668】[cqoi2012]交换棋子 费用流
    【BZOJ4372】烁烁的游戏 动态树分治+线段树
    【BZOJ3470】Freda’s Walk 概率与期望
    【BZOJ2087】[Poi2010]Sheep 几何+DP
    【BZOJ4428】[Nwerc2015]Debugging调试 记忆化搜索+分块
    【BZOJ2137】submultiple 高斯消元求伯努利数
  • 原文地址:https://www.cnblogs.com/klxs1996/p/12683973.html
Copyright © 2011-2022 走看看