TCP的拥塞控制算法:慢启动算法、拥塞避免算法,快速重传与超时重传算法,快速恢复算法

目录

什么是拥塞控制,为什么需要拥塞控制

慢启动

拥塞避免

快速重传与超时重传算法

快速恢复算法

 写在最后


什么是拥塞控制,为什么需要拥塞控制

       拥塞通常是指从随着网络中的主机增加其发送速率并因为网络的原因使网络变得十分拥挤,此时会经常发生丢包现象,导致网络的传输效率急剧降低。分组的超时重传重复收到的分组确认ACK报文,通常被作为网络拥塞的标志

        通常局域网近似于理想网络,最大带宽大小固定,几乎无抖动,几乎不会因为网络原因丢包,几乎不会发生乱序。在这种网络下,通常不会发生拥塞,发送方一开始便向网络发送多个报文段,直至达到接收方通告的窗口(滑动窗口协议)大小为止。当发送方和接收方处于同一个局域网时,这种方式是可以的。

        但是如果不是局域网(比如广域网)的情况下,在发送方和接收方之间存在多个路由器和一些速率较慢的链路,有时还会出现某些链路断开或者各种原因导致的路由路径切换,就有可能出现一些问题。比如中间突然出现一段速率慢的链路导致中间路由器必须要缓存分组,但其缓存的能力有限,耗尽存储器的空间后必须丢弃报文。那么这种情况下,我们就需要引入拥塞控制算法,来避免拥塞的发生。

        在TCP里,使用三个窗口进行流量控制,分别是:

  • 接收窗口rwnd(receive window)
  • 发送窗口swnd(send window)
  • 拥塞窗口cwnd(congestion window)

        这3个窗口的定义与关系可以参见文章:TCP的三个窗口

       正如我们已经知道的,TCP协议除了用swnd和rwnd进行流量控制外,还引入了cwnd来进行拥塞控制。拥塞避免(cwnd)是发送方使用的流量控制方法,而滑动窗口(swnd, rwnd)则是接收方使用的流量控制方法。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的处理能力处理速度大小有关。

        另外TCP的拥塞控制算法包括4大算法,分别是:

  • 慢启动算法
  • 拥塞避免算法
  • 拥塞发生算法
  • 快速恢复算法

慢启动

        TCP是一个“无私”的协议,当它检测到拥塞发生时,它就会主动降低发送速度,以避免拥塞变得更加严重,主动来帮助网络恢复正常状态。为了避免拥塞,TCP在最开始的阶段:先将拥塞窗口cwnd设置1个mss长度,然后有一个以指数形式增长的过程称为慢启动。

         在文章TCP的三个滑动窗口,swnd, cwnd, rwnd中,我们已经知道, 发送窗口swnd的大小是由cwnd拥塞窗口和接收方的rwnd接收窗口大小(swnd= min[rwnd, cwnd])中比较小的那个值来决定的。

        本文章中为了简单讨论慢启动的模型,我们提出二个假设

  • 发送窗口swnd完全由网络的拥塞程度决定                

          我们假设接收端主机的缓冲区足够大或者说接收端主机的处理能力足够快,使得接收窗口总是足够大,进而可以得出,发送窗口swnd的大小就完全是由拥塞窗口cwnd的大小来决定,即完全由网络的拥塞程度决定。

  • 以MSS的个数做为cwnd的单位

         并且我们假设需要发送的TCP报文足够大并且MSS设置成了合适的值,那么使得TCP报文总是以一个MSS的长度来发送任意一个报文,并且不会产生IP分片。这们我们就可以用MSS的个数来取代字节个数来做为CWND的窗口大小的单位。

         理解二个概念:

  • 初始cwnd
  • 慢启动门限ssthresh

TCP刚刚开始传输数据时,会从一个较小的cwnd = 1开始,然后逐步增长到sshthresh的过程称为慢启动,这个慢启动过程中的增长算法很简单:发送方每从网络上收到一个 ack,拥塞窗口 cwnd的值就会加 1。(初始化时:cwnd为1个MSS, ssthresh为65535个字节)

如图所示,

1,发送方最开始(横坐标1)时,只发送1个数据包到接收方---------cwnd的大小为1(纵坐标)

2,当发送方收到第1次发送的1个数据包的ACK后,将cwnd的大小加1成2(1+1=2),再发送2个数据包给接收方(横坐标2)

3,当发送方收到第2次发送的2个数据包的2个ACK后,将cwnd的大小加2成4(1+1+2=4),再发送4个数据包给接收方(横坐标3)

4,当发送方收到第3次发送的4个数据包的4个ACK后,将cwnd的大小加4成8(1+1+2+4=8),再发送4个数据包给接收方(横坐标3)

5,依此类推,直到cwnd>ssthresh,则结束慢启动过程进入到拥塞避免阶段

 我们可见在慢启动阶段cwnd是以指数的形式增长的,直到拥塞窗口大小大于门限值为止。

拥塞避免

当TCP经过慢启动阶段,wnd>ssthresh时,就开始使用拥塞避免算法来进行拥塞控制,这个阶段cwnd是以线性方式增长的,每次收到前面发出去的所有包时,cwnd = cwnd + 1(实际是每收到一个ACK, cwnd = cwnd + 1/cwnd),cwnd线性增长直到检测到拥塞发生。

见横坐标从6开始的,每一个RTT,cwnd最多增加1。


 

快速重传与超时重传算法

首先, 我们要区别快速重传与超时重传。

当接收方发现重复的收到三次或者更多个前一个包的 ACK时,就说明中间丢了一个报文学,这时候,发送端就不必等待超时再重传,而是可以直接快速地启动重传---------这就是快速重传

当接收方直到超时,也没有收到ACK和重复时,发送方TCP发送定时器超时后,也会主动发起重传------------这就是超时重传

发生超时重传和发生快速重传时,拥塞控制的算法是不一样的,当发生快速重传时,就引入了快速重传的算法。

  • 超时重传时的拥塞控制算法:

超时重传发生时,说明很长一段时间内,都没有数据包从发送方到达接收方(因为接收方每收到一个更新的报文就会重复发送回一个老的ACK),那么大概率是网络拥塞很严重,做为被设计成无私的网络的TCP,会快速的降低并牺牲自己的发送速率,来帮忙网络从拥塞状态恢复回正常状态。

所以此时,执行的算法是:

         ssthresh 设为当前 cwnd的一半,即cwnd/2

         再把cwnd 重置为 1

我们可以看到超时重传算法的影响是很大的,一旦发生了超时重传,吞吐量一下子就降到最低,重新开始爬坡,这里往往会造成网速的剧烈降低。

  • 快速重传时的拥塞控制算法:

因为接收方每收到一个更新的报文就会重复发送回一个老的ACK,所以当发送方重复的收到3个ACK重复报文时,发送方就认为之前发送的对应的那个报文已经丢失,但TCP超时定时器还没有超时,此时发送方不需要等待超时后再来重发报文,而是当它收到第3个重复的ACK时就启动重发,这个过程我们称之为快速重传。

这种情况下,TCP认为网络状态是良好的,只是偶尔丢了一个包而已,没有必要重启慢启动算法,从头开始,所以它会执行如下比较温和的算法,以避免对网络吞吐量的巨大跳动。

更新cwnd和ssthresh

        cwnd = cwnd/2,也就是设置为当前cwnd的一半

        ssthresh = cwnd, sshresh设置成调整后的cwnd

然后开始使用快速恢复算法来做拥塞避免(见下一章),对比上图,我们可以看到快速恢复算法,对网络吞吐量的影响比较小,流量会比较平滑

快速恢复算法

我们都知道,在真实网络中,由于网络抖动,以及网络路由切换,网络丢包等各种原因,IP报文抵达接收方时可能是乱序的,既后发的IP报文先到达,这就会导致TCP层数据报文的失序。

1,接收方在收到一个失序的报文段时, 接收方TCP协议栈软件会立即产生一个 ACK(一个重复的ACK)给发送方,该重复的 ACK的目的在于让对方知道收到一个失序的报文段(有比本TCP报文更早发送的TCP报文没有到达接收端),并告诉对方自己希望收到的TCP报文的序号。

2,发送方在重复收到上面所讲的ACK报文后,发送方并不知道这个重复的ACK产生的原因是由于前面有被发送出去的TCP报文丢失,不是说只是因为乱序了,前面发送出去的TCP报文被延时了,所以比后面发送的TCP报文更迟的到达接收方。

3,此时,发送方是用收到的重复的ACK报文的数量来判定是“丢包”了,还是“延迟”了的,如果只收到1-2个重复的ACK,发送方会认为只是偶尔“延迟”了,而如果收到3个或者更多的重复的ACK,则认为是“丢包”了。

如果只是偶尔的延迟,并且延迟时间较短,还不到触发超时重传,则不需要进行处理,发送端继续按正常的拥塞避免算法运行则可以。

如果发送方重复收到3个或者以上的重复ACK,意味着丢包了,但接收方是能持续收到新报文的(接收方只有在收到新报文时,才能产生并发送重复的ACK),那就意味着网络状态还是好的,认为只是“丢包”了。那和以意味着,网络并没有发生拥塞,只是发生了偶发的丢包,所以这时候,发送方在快速重传后没有必要重新执行慢启动算法,来大幅度的减少发送数据量,只需要重发报文,并执行拥塞避免算法就行,这就是快速恢复算法

更新cwnd和ssthresh

        cwnd = cwnd/2,也就是设置为当前cwnd的一半

        ssthresh = cwnd, sshresh设置成调整后的cwnd

开始快速恢复

        其实这一步就是开始执行正常的拥塞避免算法,每次cwnd + 1

 写在最后

注意本文是在rwnd永远大于cwnd的理想模型下讨论的,实际网络中,拥塞避免(cwnd)是发送方使用的流量控制方法,而滑动窗口(swnd, rwnd)则是接收方使用的流量控制方法, 发送窗口swnd= min(rwnd, cwnd),所以实际上发送窗口是由rwnd和cwnd中较小的来控制的。实际分析问题的时候一定要记住这一点。

  • 14
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值