拥塞控制简介
TCP会根据网络的拥堵程序来改变数据包发送的速率。如果网络卡顿的话,会降低发送速率,如果网络顺畅的话,会提高发送速率。
拥塞控制和流量控制的区别
流量控制 针对的是 发送窗口 和 接收窗口之间的关系,是用来保证发送和接收之间的收发均衡。
拥塞控制 针对的是 网络拥堵情况 , TCP会根据网络拥堵情况来调整发送速率。
拥塞控制的原因
如果网络卡顿的时候,还以一个很大的速率发送数据包的话,由于网络卡顿,数据包的延迟时间会很大,导致大量的数据包重发,这不仅会造成资源浪费,还会进一步加重网络负担,加重网络的拥堵程度。
如果网络通畅的话,如果发送速率很低的话,网络的利用率会低下,需要提高发送速率。
拥塞控制
我们都知道拥塞控制会根据网络拥堵程度来调整发送速率。
网络拥堵程度是怎么判定的呢? 发送速率是怎么调整的呢?
这两个问题就是拥塞控制的核心。
1、首先说下怎么判定网络拥堵程度
如果出现了超时重传或者快速重传,就说明网络拥堵了。
如果接收到ack包,就说明网络畅通了。
2、 发送速率怎么调整
2.1、 首先TCP引入了 拥塞窗口 cwnd 的概念, 拥塞窗口 的大小随着网络的波动而变化。
网络没有阻塞,cwnd就增大
网络发生阻塞,cwnd就减小
发送窗口 swnd 根据 拥塞窗口 cwnd 和 接收窗口 rwnd 而定
swnd = min(cwnd,rwnd)
2.2、 TCP将发送分成了四个阶段:慢启动、 拥塞避免、 拥塞发生、 快速恢复。
慢启动
TCP刚建立连接的时候,采用慢启动,因为这个时候不知道网络是什么情况,会慢启动。
慢启动的规则就是: 每当收到一个ack包,就将cwnd+1。
例子如下:
1、 TCP初始化的时候,cwnd = 1,代表可以发送一个数据包
2、 每当接收一个ack包,cwnd+1,也就是代表可以发送两个数据包。
3、 当可以发送两个数据包的时候,每次可以收到两个ack包,cwnd += 2,代表可以发送4个数据包。
4、下一次cwnd = 8,可以发送8个数据包
从流程可以看出,慢启动虽然叫慢启动,但是cwnd却是指数增长的。
慢启动什么时候结束呢?
TCP设置了一个阈值 ssthresh (slow start threshold)
1、 cwnd < ssthresh,使用慢启动算法 2、 cwnd >= ssthresh,使用拥塞避免算法
一般来说,ssthresh = 65535字节
拥塞避免
拥塞避免的做法是每次收到一个ack包,cwnd 每次增加 1 / cwnd。
我们假设发送窗口中的所有数据发送和接收ack为一轮,这样的话,一轮过后,cwnd只增加1。拥塞避免是线性增长。
拥塞发生
如果没有出现超时重传或者快速重传的问题,就会一直处于拥塞避免阶段,一直线性增加。
如果出现超时重传或者快速重传的时候,说明当前网络发生拥堵,会进入拥塞发生阶段。
拥塞发生时,超时重传和快速重传对应的处理方法不一样
超时重传
ssthresh /= 2; cwnd = 1;
然后进入慢启动状态。
快速重传 TCP认为发生快速重传时的网络要比超时重传的网络要好,因为快速重传还能接收到3个相同的ack包,说明网络还可以。
所以两者对应着不同的处理方法。
cwnd /= 2 ssthresh = cwnd
然后进入快速恢复状态
快速恢复
当进入快速恢复的时候,说明网络还可以,可以快速恢复,也就是cwnd的值不会忽然变小。
1、 首先会重传丢失的数据
2、 将cwnd += 3
3、 如果收到的是导致进入快速恢复状态的ack,就将cwnd+1,所以叫快速恢复,直接+1。
4、 如果收到的是新的数据包的ack,说明之前重传的数据已经被成功接收了,将cwnd设置为ssthresh,也就是快速重传前的cwnd的一半,然后进入拥塞避免状态。
总结
|