TCP 实现拥塞控制

拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。

实际上,拥塞控制主要有这几种常用算法

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

慢启动算法

慢启动算法,表面意思就是,别急慢慢来。它表示TCP建立连接完成后,一开始不要发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。

  • TCP连接完成,初始化cwnd = 1,表明可以传一个MSS单位大小的数据。
  • 每当收到一个ACK,cwnd就加一;
  • 每当过了一个RTT,cwnd就增加一倍; 呈指数让升

图片


为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slow start threshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwnd >ssthresh时,进入了拥塞避免算法。

拥塞避免算法

一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值

  • 每收到一个ACK时,cwnd = cwnd + 1/cwnd
  • 当每过一个RTT时,cwnd = cwnd + 1

显然这是一个线性上升的算法,避免过快导致网络拥塞问题。


图片

拥塞发生

当网络拥塞发生丢包时,会有两种情况:

  • RTO超时重传
  • 快速重传

如果是发生了RTO超时重传,就会使用拥塞发生算法

  • 慢启动阀值sshthresh =  cwnd /2
  • cwnd 重置为 1
  • 进入新的慢启动过程


图片


这真的是辛辛苦苦几十年,一朝回到解放前。其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。

图片image.png

慢启动阀值ssthresh 和 cwnd 变化如下:

  • 拥塞窗口大小 cwnd = cwnd/2
  • 慢启动阀值 ssthresh = cwnd
  • 进入快速恢复算法

快速恢复

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

正如前面所说,进入快速恢复之前,cwnd 和 sshthresh已被更新:

展开阅读全文

本文系作者在时代Java发表,未经许可,不得转载。

如有侵权,请联系nowjava@qq.com删除。

编辑于

关注时代Java

关注时代Java