拥塞控制和流量控制的区别

  • 流量控制就是让发送方的发送速率不要太快,让接收方来得及接收。如果接收方来不及接收发送方发送的数据,那么就会有分组丢失。在 TCP 中利用可边长的滑动窗口机制可以很方便的在 TCP 连接上实现对发送方的流量控制。
  • 拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。常用的解决方法有:慢开始和拥塞避免、快重传和快恢复。拥塞控制往往是一种全局的。

什么是拥塞窗口?和发送窗口有什么关系呢?

拥塞窗口 cwnd是发送方维护的一个的状态变􏰁,它会根据网络的拥塞程度动态变化的
我们在前面提到过发送窗口 swnd 和接收窗口 rwnd 是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。
拥塞窗口 cwnd 变化的规则:

  • 只要网络中没有出现拥塞, cwnd 就会增大;
  • 但网络中出现了拥塞, cwnd 就减少;


    拥塞控制主要是四个算法

    慢启动

    在连接刚建立后,当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。
    这里假定拥塞窗口 cwnd 和发送窗口 swnd 相等,下面举个栗子:

  • 连接建立完成后,一开始初始化 cwnd = 1 ,表示可以传一个 MSS 大小的数据。

  • 当收到一个 ACK 确认应答后,cwnd 增加 1,于是一次能够发送 2 个
  • 当收到 2 个的 ACK 确认应答后, cwnd 增加 2,于是就可以比之前多发2 个,所以这一次能够发送 4 个
  • 当这 4 个的 ACK 确认到来的时候,每个确认 cwnd 增加 1, 4 个确认 cwnd 增加 4,于是就可以比之前多发 4 个,所以这一次能够发送 8 个。

image.png
可以看出慢启动算法,发包的个数是指数性的增⻓

拥塞避免

当拥塞窗口 cwnd 「超过」慢启动⻔限 ssthresh 就会进入拥塞避免算法。
一般来说 ssthresh 的大小是 65535 字节。
那么进入拥塞避免算法后,它的规则是:每当收到一个 ACK 时,cwnd 增加 1/cwnd。

接上前面的慢启动的栗子,现假定 ssthresh 为 8 :

  • 当 8 个 ACK 应答确认到来时,每个确认增加 1/8,8 个 ACK 确认 cwnd 一共增加 1,于是这一次能够发送 9 个 MSS 大小的数据,变成了线性增⻓

image.png
拥塞避免算法就是将原本慢启动算法的指数增⻓变成了线性增⻓,还是增⻓阶段,但是增⻓速度缓慢了一些。

拥塞发生算法

当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:

  • 超时重传
  • 快速重传

超时重传的拥塞发生算法

当发生了「超时重传」,则就会使用拥塞发生算法。 这个时候,ssthresh 和 cwnd 的值会发生变化:
ssthresh(慢启动门限) 设为 cwnd/2 ,
cwnd(窗口大小) 重置为 1
image.png

快速重传的拥塞发生算法

TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,则

  • cwnd(窗口大小) = cwnd(窗口大小)/2 ,也就是设置为原来的一半;
  • ssthresh(慢启动门限) = cwnd (窗口大小);
  • 进入快速恢复算法

快速恢复

快速重传算法执行完会迅速进入到快速恢复算法
进入快速恢复算法如下:

  • 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了); 􏰀
  • 传丢失的数据包;
  • 如果再收到重复的 ACK,那么 cwnd 增加 1;
  • 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说 明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进 入拥塞避免状态;
    image.png