4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

文章目录


本文大部分内容来自小林coding《图解网络》,感谢分享,简单整理。

一:为什么需要拥塞控制

自开始接触TCP以来我们一直把目光集中在的发送方和接收方这两个点上,并不关心网络传输中发生了什么。但是计算机网络是很复杂,所处的环境十分繁杂,有的时候会因为其他主机之间的通信而变得网络拥堵

在网络出现拥堵的时候,如果继续发送大量数据包,极有可能导致数据包时延、丢失等,这时TCP就要重传数据,但是一重传反而又加剧了网络的负担,是一个恶性循环

因此TCP作为一个可靠的协议,不能忽略网络中的事情,应该被设计成一个有情商的协议,网络堵塞少发点,网络畅通正常发。于是TCP的拥塞控制就是避免发送方的数据填满整个网络

拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.

二:拥塞窗口

拥塞控制cwnd是发送方维护的一个状态变量,它会根据网络的拥塞程度动态变化
前面讲到的发送窗口swnd和接受窗口rwnd是约等于的关系,这里由于加入了拥塞窗口,因此swnd=min(cwnd,rwnd)

拥塞窗口变化规则

  • 网络中没有出现拥塞-cwnd就会增大
  • 网络中出现了拥塞-cwnd就会减少

每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小作比较,取较小值作为实际发送的窗口

三:如何知道当前网络是否出现拥塞

其实道理很简单,只要发送方没有在规定时间内接受到ACK报文,也就是发生了超时重传,就会认为网络出现了拥塞

四:拥塞控制算法详解

主要是四个算法

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

(1)慢启动

TCP在刚建立完连接后,首先有一个慢启动的过程。也就是一点一点的提高发送数据包的数量,其实也很好理解,如果一上来就大量发送数据,这岂不是给网络添堵吗

慢启动算法规则:当发送方每收到一个ACK,拥塞窗口cwnd大小+1

如下图,假定拥塞窗口cwnd和发送窗口swnd相等
4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

  • 连接建立完成后,一开始初始化cwnd为1,表示可以传一个MSS大小的数据
  • 当收到一个ACK确认应答后,cwnd增加1,于是一次可以发送2个
  • 当收到2个ACK时,cwnd曾家2,于是这次可以发送4个
  • 当4个都到来时,每个cwnd增加一个,那么这次就可以发送8个

可以看出慢启动算法,发送数据包的数量是呈现指数级的增长的,当超过某个阈(慢启动阈值)值时,按照线性方式增长

4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)
其中这个阈值就是ssthresh(slow start threshold)

  • 当cwnd>ssthresh时,使用慢启动算法
  • 当cwnd>=ssthresh时,使用拥塞避免算法

(2)拥塞避免

前面说过,当拥塞窗口cwnd超过慢启动门限ssthresh时就会进入拥塞避免算法。
一般来说,ssthresh=65535字节

拥塞避免算法规则:每收到一个ACK时,cwnd增加1/cwnd
接上面的例子,如下图
4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

  • 当8个ACK到来时,每个确认增加1/8,8个ACK于是cwnd一共增加1,于是这一次可以发送9个MSS大小的数据,变为了线性增长

因此拥塞避免算法将原本慢启动算法的指数级增长变为了线性增长,因此增长速度变得缓慢了很多。

虽然速度变慢了,但是毕竟一直在增长,所以网络就会慢慢进入拥塞的状态,也就会产生丢包,这时就需要对丢失的数据包进行重传

当触发重传时,进入拥塞发生算法

(3)拥塞发生

当网络出现拥塞,发生数据包重传,重传主要有两种

  • 超时重传
  • 快速重传

这两种重传使用的拥塞发生算法是不同的。

A:发生超时重传时的拥塞发生算法

这个时候,ssthreshcwnd的值会发生变化

  • ssthresh设为cwnd/2
  • cwnd重置为1

4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

如上图,发生超时重传就意味着“一夜回到*”,之后就重新开始了慢启动。这种方式很明显太激进了,几乎是戛然而止,会造成网络卡顿,就类似于正在秋明山上飘逸,突然来一个急刹车。

B:发生快速重传时的拥塞发生算法

快速重传算法是当接收方发现丢了一个中间包时,发送三次前一个包的ACK,于是发送单就会快速重传,不必等待超时再重传。

TCP认为这种情况不严重,因为大部分没有丢失,于是ssthreshcwnd变化如下

  • cwnd=cwnd/2
  • ssthresh=cwnd
  • 进入快速恢复算法

(4)快速恢复

快速重传和快速恢复算法一般同时使用,快速恢复算法认为,你还能收到3个重复ACK说明网络也不那么糟糕嘛,所以没有必要像RTO超时那样强烈

因此首先

  • cwnd=cwnd/2
  • ssthresh=cwnd

然后进入快速恢复

  • 拥塞窗口cwnd=ssthresh+3(意思是确认有3个数据包收到了)
  • 重传丢失的数据包
  • 如果再收到重复的ACK,那么cwnd+1
  • 如果收到新数据的ACK后,就把cwnd设置为第一个中的ssthresh的值,原因是该ACK确认了新的数据,说明从duplicated ACK的数据都已经收到,该恢复过程已经结束,可以回到恢复之前的状态了,也就是再次进入拥塞避免状态。
    4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

五:拥塞算法完整示意图

如下图是一个比较经典的拥塞算法的过程图
4-8:TCP协议之拥塞控制(慢启动、拥塞避免、拥塞发生和快速恢复)

上一篇:misc大杂烩2


下一篇:MyBaties --day1