TCP拥塞控制

所谓拥塞控制就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制和流量控制都是太那个个控制发送方发送数据的速率来达到效果的。

区别在于:拥塞控制是让网络能够承受现有的网络负荷,它是一个全局性的过程,设计所有主机,路由器以及网络传输性能有关的所有因素。而流量控制往往是指点对点的通信量的控制,即接收端控制发送端,即抑制发送端发送数据的速率,以便使接收端来得及接收。

因此,发送方在确定发送报文段的速率时,既要根据接收方的接收能力,又要从全局考虑不要使网络发送拥塞,因此,TCP协议要求发送方维护两个窗口:

  • 接收窗口rwnd,接收方根据目前接收缓存大小所设定的窗口值
  • 拥塞窗口cwnd,发送方根据自己估算的网络拥塞程度设置的窗口值,反映了网络的当前容量。

发送窗口的上限取得是接收窗口rwnd和拥塞窗口cwnd中较小的一个,即min(rwnd,cwnd)

接受窗口根据TCP报文首部的窗口字段确定,拥塞窗口怎么维护呢?为了更好地对传输层进行拥塞控制,给出了下面四种算法:慢启动、拥塞避免、快重传、快恢复

拥塞控制算法

慢启动算法

在TCP刚连接好,开始发送TCP报文段时,先令将拥塞窗口(cwnd)设置为一个较小的值(通常为1),在每收到一个对新的报文段确认后,再将cwnd加1,慢开始算法,每经过一个传输轮次(即往返RTT),拥塞窗口cwnd就会加倍,即呈指数形式增加,当慢开始算法把拥塞窗口cwnd增大到一个阈值ssthresh,改用拥塞避免算法。

拥塞避免算法

拥塞避免算法的做法是:发送端的拥塞窗口cwnd每经过一个往返RTT,按线性规律缓慢增长。

网络拥塞的处理

当网络出现拥塞,不管是在慢开始阶段还是拥塞避免阶段,只要发送方检测到超时事件发送,就要把慢开始阈值ssthresh设置为出现拥塞时的发送方cwnd的一半(但不能小于2),然后将拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的是迅速减少主机发送到网络中的分组数,使得发送拥塞的路由器有足够的时间把队列中积压的分组处理完毕。

慢开始和拥塞避免算法实现过程如图所示:
tcp-crowding

注意:在慢开始阶段,若2cwnd>ssthresh,则下一个RTT的cwnd应等于ssthresh,而不是2cwnd,即cwnd不能超过ssthresh值

快重传和快恢复

快重传和快恢复算法是对慢开始和拥塞避免算法的改进

  1. 快重传
    当发送方连续收到三个重复的ACK报文,直接重传对方尚未收到的报文段,而不必等待那个报文段设置的重传计时器超时。
  2. 快恢复
    当发送端收到连续三个冗余ACK时,就执行“乘法减少”算法,把慢开始阈值ssthresh设置为出现拥塞时发送方cwnd的一半。与慢开始将拥塞窗口cwnd设置为1的不同之处,它把cwnd的值设置为慢开始阈值ssthresh减半后的数值,然后执行拥塞避免算法,使拥塞窗口缓慢线性增大。

实现过程如下图所示:
tcp-fast

总结

发送方发送窗口的实际大小由流量控制和拥塞控制共同决定,流量控制窗口rwnd由接收方在TCP报文段首部窗口字段提供,而拥塞控制窗口由发送方对当前网络环境的预估,结合慢开始和拥塞避免或者更优算法快传和快恢复算法来进行拥塞控制。最终发送方实际的发送窗口大小是由rwnd和cwnd中较小的那一个确定的。

参考文献:https://juanha.github.io/2018/05/05/tcp/