拥塞控制:防止过多的数据注入网络中,可以使网络中的路由器或链路不致过载。

image.png

拥塞:当网络复杂超过其承受能力,会导致吞吐量下滑,网络进入拥塞状态。

1999年公布的因特网建议标准RFC 2581定义了进行拥塞控制的四种算法:

  • 慢开始 slow-start
  • 拥塞避免 congestion avoidance
  • 快重传 fast retransmit
  • 快恢复 fast recovery

慢开始

发送方维持一个叫做拥塞窗口 cwnd (congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。以后我们就知道,如果再考虑到接收方的接收能力,那么发送窗口还可能小于拥塞窗口。

发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。

当发送方没有按时收到应当到达的确认报文,就猜想网络出现了拥塞。

基本思路
由小到大逐渐增大发送窗口,即由小到大逐渐增大拥塞窗口数值(发送方让自己的发送窗口等于拥塞窗口)。
具体说:通常在刚刚开始发送报文段时,先把拥塞窗口cwnd设置为一个最大报文段MSS的数值(1460字节)。而在每收到一个对新的报文段的确认后,把**拥塞窗口增加至多一个MSS的数值**。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。

(因此,发送窗口的数据量会成倍地增加。1,2,4,8,16……)

为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。
慢开始门限ssthresh的用法如下:

  • 当cwnd < ssthresh时,使用上述的慢开始算法。
  • 当cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
  • 当cwnd = ssthresh时,既可使用慢开始算法,也可使用拥塞避免算法。

拥塞避免

基本思路:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT(表示从发送端发送数据开始,到发送端收到来自接收端的确认)就把发送方的拥塞窗口cwnd加1个MSS的大小,而不是加倍。这样,拥塞窗口cwnd 按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。

无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)[插图]。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

image.png

乘法减小和加法增大

在TCP拥塞控制的文献中经常可看见“乘法减小”(Multiplicative Decrease)和“加法增大”(Additive Increase)这样的提法。“乘法减小”是指不论在慢开始阶段还是拥塞避免阶段,只要出现超时(即很可能出现了网络拥塞),就把慢开始门限值ssthresh减半,即设置为当前的拥塞窗口的一半(与此同时,执行慢开始算法)。当网络频繁出现拥塞时,ssthresh值就下降得很快,以大大减少注入到网络中的分组数。而“加法增大”是指执行拥塞避免算法后,使拥塞窗口缓慢增大,以防止网络过早出现拥塞。上面两种算法合起来常称为AIMD算法(加法增大乘法减小)。

快重传

快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等待自己发送数据时才进行捎带确认。

由于发送方能尽早重传未被确认的报文段,因此采用快重传后可以使整个网络的吞吐量提高约20%。
image.png

快恢复

(1) 当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把慢开始门限ssthresh减半。这是为了预防网络发生拥塞。请注意,接下去不执行慢开始算法。

(2) 由于发送方现在认为网络很可能没有发生拥塞(如果网络发生了严重的拥塞,就不会一连有好几个报文段连续到达接收方,也就不会导致接收方连续发送重复确认),因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。

image.png

image.png

image.png