在TCP/IP中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有FRR,如果数据包丢失了,TCP将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。快速重传快速恢复算法是在4.3BSD Reno中提出的,并在RFC 2001和RFC2581中描述。   FRR也指误拒绝率(false rejection rate),一个在生物安全系统中使用的术语。

1. Tahoe

Tahoe算法是TCP的早期版本。它的核心思想是:让cwnd以指数增长方式迅速逼近可用信道容量,然后
慢慢接近均衡。Tahoe包括3个基本的拥塞控制算法:慢启动、拥塞避免、快速重传。

我们可以看到,Tahoe不存在快速恢复算法。这也是它的不足之处。
在收到3个重复ACK或者在超时的情况下,Tahoe置cwnd为1,然后进入慢启动阶段。这一方面会引起网
络的激烈震荡,另一方面大大降低了网络的利用率。
也就是说,一旦发现掉包,那么cwnd就被打回原形。

没有快速恢复算法,在恢复丢失数据包期间,不能发送新的数据包,这段时间的吞吐量为0。而实际上
如果利用这段时间来发送适量的新数据包,可以大大的提高丢包时的传输效率。这就是快速恢复名称的
由来。

2. Reno

Reno与Tahoe相比,增加了快速恢复阶段,也就是说,完成快速重传后,进入了拥塞避免阶段而不是慢
启动阶段。
Reno prevents the communication path from going empty after Fast Retransmit.
Reno sender uses additional incoming dup ACKs to clock subsequent outgoing packets.
算法描述:

  1. step1:
  2. if ( dupacks >= 3 ) {
  3. ssthresh = max( 2 , cwnd / 2 ) ;
  4. cwnd = ssthresh + 3 * SMSS ;
  5. }
  6. step2:重传丢失的分组
  7. step3:此后每收到一个重复的ACK确认时,cwnd++
  8. step4:当收到对新发送数据的ACK确认时,cwnd = ssthresh,这个ACK能够对那些在
  9. 丢失的分组之后,第一个重复ACK之前发送的所有包进行确认。
  1. step1:
  2. if ( dupacks >= 3 ) {
  3. ssthresh = max( 2 , cwnd / 2 ) ;
  4. cwnd = ssthresh + 3 * SMSS ;
  5. }
  6. step2:重传丢失的分组
  7. step3:此后每收到一个重复的ACK确认时,cwnd++
  8. step4:当收到对新发送数据的ACK确认时,cwnd = ssthresh,这个ACK能够对那些在
  9. 丢失的分组之后,第一个重复ACK之前发送的所有包进行确认。

在快速恢复阶段,每收到重复的ACK,则cwnd加1;收到非重复ACK时,置cwnd = ssthresh,
转入拥塞避免阶段;如果发生超时重传,则置ssthresh为当前cwnd的一半,cwnd = 1,重新进入
慢启动阶段。
Reno快速恢复阶段退出条件:收到非重复ACK。

3. NewReno

Reno不能有效的处理多个分组从同一数据窗口丢失,于是有了NewReno。
NewReno修改了Reno的快速恢复算法,处理一个窗口中的多个报文段同时丢失时出现的“部分确认”
(Partial ACKs,它在快速恢复阶段到达并且确认新数据,但它只确认进入快速重传之前发送的一部分
数据)。
在这种情况下,Reno会退出快速恢复状态,等待定时器溢出或者重复的确认ACK到达,但是NewReno
并不退出快速恢复状态,而是:

  1. step1:重传紧接着那个部分ACK之后的报文段,拥塞窗口等于其减去partial ACK的部分。
  2. step2:对于得到确认的新数据,cwnd++
  3. step3:对于第一个或每一个Partial ACK,重传定时器复位。且每次都重置cwnd = 原cwnd / 2。
  1. step1:重传紧接着那个部分ACK之后的报文段,拥塞窗口等于其减去partial ACK的部分。
  2. step2:对于得到确认的新数据,cwnd++
  3. step3:对于第一个或每一个Partial ACK,重传定时器复位。且每次都重置cwnd = 原cwnd / 2。

NewReno算法中有变量recover,其值为检测到丢包时的最大发送序列号。只有当recover之前的数据
报都确认完后,才能推出快速恢复,进入拥塞避免阶段。
当超时时,将发送的最大序列号保存在recover变量中,结束快速恢复过程。
NewReno不支持SACK。

4. SACK

During Fast Recovery, SACK maintains a variable calledpipe that represents the estimated number
of packets outstanding in the path. 
 The sender only sends new or retransmitted data when the estimated number of packets in the path
is less than the congestion window. The variable pipe is incremented by one when the sender either
sends a new packet or retransmits an old packet. It is decremented by one when the sender receives
a dup ACK packet with a SACK option reporting the new data has been received at the receiver.

Use of the pipe variable decouples the decision of when to send a packet from the decision of which
packet to send.

The sender maintains a data structure, thescoreboard, that remenbers acknowledgements from
previous SACK option. When the sender is allowed to send a packet, it retransmits the next packet
from the list of packets inferred to be missing at the receiver. If there are no such packets and the
receiver's advertised window is sufficiently large, the sender sends a new packet.

When a retransmitted packet is itself dropped, the SACK implementation detects the drop with a
retransmit timeout, retransmitting the dropped packet and then slow-starting.
The sender exits Fast Recovery when a recovery acknowledgement is received acknowledging
all data that was outstanding when Fast Recovery was entered.

  1. step 1:
  2. Fast Recovery is initiated,
  3. pipe -1 ( for the packet assumed to have been dropped).
  4. pipe +1 ( for the packet retransmitted)
  5. cwnd = cwnd / 2
  6. step 2 :
  7. If pipe <= cwnd,sender retransmits packets inferred to be missing.
  8. If there are no such packets, sender sends new packets.
  9. step 3:
  10. when sender receives a dup ACK, pipe = pipe - 1
  11. when sender sends a new / retransmit an old packet, pipe = pipe +1
  12. step 4:
  13. For partial ACKs :pipe = pipe - 2
  14. (one for original dropped packet,one for retransmitted packet)
  15. step 5:
  16. all packets outstanding before Fast Recovery were ACKed,
  17. exit Fast Recovery.
  18. 当退出Fast Recovery时,cwnd同样恢复成ssthresh,进入拥塞避免。
  1. step 1:
  2. Fast Recovery is initiated,
  3. pipe -1 ( for the packet assumed to have been dropped).
  4. pipe +1 ( for the packet retransmitted)
  5. cwnd = cwnd / 2
  6. step 2 :
  7. If pipe <= cwnd,sender retransmits packets inferred to be missing.
  8. If there are no such packets, sender sends new packets.
  9. step 3:
  10. when sender receives a dup ACK, pipe = pipe - 1
  11. when sender sends a new / retransmit an old packet, pipe = pipe +1
  12. step 4:
  13. For partial ACKs :pipe = pipe - 2
  14. (one for original dropped packet,one for retransmitted packet)
  15. step 5:
  16. all packets outstanding before Fast Recovery were ACKed,
  17. exit Fast Recovery.
  18. 当退出Fast Recovery时,cwnd同样恢复成ssthresh,进入拥塞避免。

与Reno不同的是:

(1)when to send packet:由计算pipe变化决定,不再是计算cwnd变化。
(2)which packet to send:由SACK携带信息决定,反应更迅速。

问题1:在一个窗口内重复丢包会造成影响吗?

答案:会。如果只丢一个包,那么收到非重复ACK时,就能确认完本窗口内所有的包。然后进入拥塞
避免阶段。这就是Reno想达到的。
而如果丢失多个包,那么收到非重复ACK时,不能确认完本窗口内所有的包。但是,也会退出快速恢复,
进入拥塞避免阶段。

这个时候可能会发生两种情况:
(1)多次进行快速重传和快速恢复。又发现丢包,再次进入快速重传和快速恢复。注意,每次进入
快速重传和快速恢复时,ssthresh和cwnd都要减半。多次丢包最终会导致ssthresh指数减小。
通过画cwnd(t)图可以发现,不仅这段时间吞吐量非常低,而且导致恢复完后拥塞避免的起点非常低,从
而导致之后的吞吐量也很低。

(2)经过多次快速重传和快速恢复,接着发生传输超时。
那么,发生传输超时需要什么样的条件呢?

1) when two packets are dropped from a window of data, the Reno sender is forced to wait for a
retransmit timeout whenever the congestion window is less than 10 packets when Fast
Recovery is initiated, and whenever the congestion window is within two packets of the receiver's
advertised window when Fast Recovery is initiated.

2) when three packets are dropped from a window of data, the Reno sender is forced to wait for
a retransmit timeout whenever the number of packets between the first and the second dropped
packets is less than 2 + 3W/4, for W the congestion window just before the Fast Retransmit.

这种情况出现的概率极大,也就是说一个窗口出现3个丢包,有大概率出现超时。当丢包时窗口大小
为15,有三个丢包,那么无论丢包的顺序如何,2次FR/FR之后,总会出现超时。
超时一般是因为未确认的数据包 > 可以使用的cwnd,不能发送新的数据,而网络中有没有足够的
重复ACK来触发FR/FR。

问题2:为什么发生拥塞时,还增加cwnd?

答案:在检测到丢包时,窗口为cwnd。这时候网络中最多有cwnd个包(in_flight < cwnd )。每当收到
一个重复的ACK,则说明有数据包离开网络,达到接收端了。那么,此时网络中还可以再容纳1个包。由
于发送端滑动窗口不能移动了,所以如果想保持in_flight,可以使cwnd++。
这样一来,可以提高吞吐量。而实际上,在fast recovery期间发送的新数据包比起发生丢包的cwnd来说,
已经是大大减少了。

性能分析

Tahoe没有快速恢复机制,在丢包后,它不仅重发了一些已经成功传输的数据,而且在恢复期间吞吐量
也不高。
利用SACK option携带的信息,我们能够提前知道哪些数据包丢失了。NewReno每个RTT内只能恢复
一个丢失的数据包,所以如果丢失了N个数据包,那么Fast Recovery就要持续N*RTT的时间,当N比较
大时,这是一段相当长的时间。而SACK则没有这个限制,依靠SACK option的信息,它能够同时恢复
多个数据包,更加快速和平稳的恢复。
当发生同一窗口多个丢包时,SACK和NewReno最终都能够较为快速和平稳的恢复过来。而Reno则经
常出现超时,然后再用慢启动来恢复,这个时候Reno的表现就如同Tahoe,会造成已接受数据的重复
传送。Reno恢复期间会出现吞吐量低、恢复时间长、不必要重发数据、恢复结束后阈值过低等一些问
题,严重的影响性能。

结论

经过上述分析我们可以看出:

It is a fundamental consequence of the absence of SACK that the sender has to choose between
the following strategies to recover from lost data:

(1)retransmitting at most one dropped packet per round-trip time

(2)retransmitting packets that might have already been successfully delivered.

Reno and New-Reno use the first strategy, and Tahoe uses the second.
With SACK, a sender can avoid unnecessary delays and retransmissions, resulting in improved
throughput.

SACK的不足

上面说了很多SACK的好话,现在来谈谈它的不足之处。

For a large BDP network where the number of packets are in flight, the procesing overhead of
SACK information at the end points can be quite overhelming because each SACK block invokes
a research into the large packet buffers of the sender for acked packets in the block, and every
recovery of a loss packet causes the same search at the receiver.

在BDP网络,这个问题尤其明显,会严重的消耗CPU而导致一系列问题。在一定程度上来说,此时
的SACK就像DOS攻击一样,每次遍历都要消耗大量CPU,时间复杂度为O(n^2),n为packets in
flight的数量。

The system overload can cause serious problem : it can cause multiple timeouts (as even packet
retransmission and receptions are delayed) and a long period of zero throughput.

当然,这是中等规模的BDP(100~1000)或大规模的BDP网络才需考虑的问题,对于一般的BDP而
言不会出现太大的问题。

转载自http://blog.csdn.net/zhangskd/article/details/7174682

https://blog.csdn.net/skc361/article/details/25893059

TCP快速重传与快速恢复原理分析(四种不同的算法)的更多相关文章

  1. TCP快速重传和快速恢复

    当tcp传送一个分组时会设置一个定时器,如果在规定的实际间隔内没有收到ACK分组,那么则重新传输该分组,但是 如果tcp收到三个连续的ACK分组,此时不管是否过超时间隔则重传该分组,具体步骤如下: 1 ...

  2. 牛客网Java刷题知识点之拥塞发生的主要原因、TCP拥塞控制、TCP流量控制、TCP拥塞控制的四大过程(慢启动、拥塞避免、快速重传、快速恢复)

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  3. TCP怎么保证证包有序传输的,TCP的慢启动,拥塞避免,快速重传,快速恢复

    TCP提供了最可靠的数据传输,它给发送的每个数据包做顺序化(这看起来非常烦琐),然而,如果TCP没有这样烦琐的操作,那么,可能会造成更多的麻烦.如造成数据包的重传.顺序的颠倒甚至造成数据包的丢失. 那 ...

  4. PHP四种基本排序算法

    PHP的四种基本排序算法为:冒泡排序.插入排序.选择排序和快速排序. 下面是我整理出来的算法代码: 1. 冒泡排序: 思路:对数组进行多轮冒泡,每一轮对数组中的元素两两比较,调整位置,冒出一个最大的数 ...

  5. php四种基础排序算法的运行时间比较

    /** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 ...

  6. php四种基础排序算法的运行时间比较!

    /** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 ...

  7. TCP协议可靠性数据传输实现原理分析

    http://blog.csdn.net/chexlong/article/details/6123087 TCP 协议是一种面向连接的,为不同主机进程间提供可靠数据传输的协议.TCP 协议假定其所使 ...

  8. Java NIO使用及原理分析 (四)(转)

    在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O.通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至 ...

  9. Java NIO使用及原理分析 (四)

    在上一篇文章中介绍了关于缓冲区的一些细节内容,现在终于可以进入NIO中最有意思的部分非阻塞I/O.通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至 ...

随机推荐

  1. 【HDU 4763】Theme Section(KMP)

    这题数据水的一B.直接暴力都能够过. 比赛的时候暴力过的.回头依照正法做了一发. 匹配的时候 失配函数 事实上就是前缀 后缀的匹配长度,之后就是乱搞了. KMP的题可能不会非常直接的出,可是KMP的思 ...

  2. Impala储存与分区

    不多说,直接上干货! hive的元数据存储在/user/hadoop/warehouse Impala的内部表也在/user/hadoop/warehouse. 那两者怎么区分,看前面的第一列. 下面 ...

  3. Android自定义组件系列【12】——非UI线程绘图SurfaceView

    一.SurfaceView的介绍 在前面我们已经会自定义View,使用canvas绘图,但是View的绘图机制存在一些缺陷. 1.View缺乏双缓冲机制. 2.程序必须重绘整个View上显示的图片,比 ...

  4. Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)(转)

    1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后, ...

  5. NO.1 You must restart adb and Eclipse多种情形分析与解决方式

    一:错误提示 The connection to adb is down, and a severe error has occured. You must restart adb and Eclip ...

  6. mac自己定义tree命令

    编辑文件: vim ~/.bash_profile 在文件末尾追加: alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____| ...

  7. UML中的用例图

    用例图构成:參与者(actor).用例(use case).子系统(subsystem) 关联(Association) 泛化(Inheritance) 就是通常理解的继承关系,子用例和父用例类似,但 ...

  8. eclipse个人插件

    1.SVN eclipse markets 安装m2e-subversion.svnkit 2.maven 本地装好mvn prefences导入maven安装目录和配置 3.单元测试覆盖率 EclE ...

  9. [BZOJ2238]Mst 最小生成树+树链剖分/并查集

    链接 题解 先构建出最小生成树,如果删的是非树边,直接输出答案 否则问题转化为,把该边删掉后剩下两个联通块,两个端点分别在两个块内的最小边权,LCT可以维护 不妨换一种思考方向:考虑一条非树边可以代替 ...

  10. php中类的持久化如何实现

    php中类的持久化如何实现 一.总结 一句话总结:PHP持久化通过serialize()  和   unserialize() 这两个函数来实现的. 1.持久化之后的对象保存到哪里? 将复杂的数组之类 ...