网络传输过程中,某段时间如果网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就会变坏,这种情况就叫做网络拥塞
为解决这个问题,TCP中使用了四种拥塞控制算法
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
1. 慢开始
发送方会维持一个拥塞窗口cwnd的状态变量,拥塞窗口的大小取决于拥塞程度,并且会在收发包过程中动态的进行变化。发送方会让本端的发送窗口等于拥塞窗口。
慢开始的核心思想:指数级由小到大逐渐增加拥塞窗口大小,如果网络出现阻塞,拥塞窗口就减小。
判断出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生重传)。
维护一个慢开始门限ssthresh状态变量:
- 当cwnd < ssthresh 时,使用慢开始算法。
- 当cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
- 当cwnd = ssthresh 时,既可以使用慢开始算法,也可以使用拥塞避免算法。
假设发送方拥塞窗口cwnd的值为1,发送窗口swnd等于拥塞窗口cwnd,那么目前发送方只能发送一个报文段,cwnd为几就能发送几个报文段,接收方收到报文段后发送回复确认,发送方收到确认报文,会将拥塞窗口的值乘2,变为2。
发送方此时一次就能发送两个报文段,接收方收到报文段后返回两次确认报文段,发送方收到之后拥塞窗口再乘2,cwnd=4。知道发送方发送16个报文段都按时收到确认报文,拥塞窗口变为32,但是这一次没有按时收到确认报文,即有报文需要重传,表示网络发生了拥塞,这时候设定ssthresh为当前窗口cwnd的一半,即ssthresh = cwnd/2 = 16。重新开始慢开始。再一次cwnd=16的时候,开启拥塞避免算法。
2. 拥塞避免算法
拥塞避免算法是让拥塞窗口缓慢增长,每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,拥塞窗口按线性规律缓慢增长。
不论是在慢开始期间还是拥塞避免期间,只要判断网络发生了拥塞ssthresh就设置为当前发送窗口大小的一半,然后重新开始执行慢开始算法,这样做的目的是迅速减少主机发送到网络中的分组数,使发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。
3. 快速重传
快速重传是对前两个机制的补充,在1988年TCP拥塞控制算法初次提出的时候只有慢开始和拥塞避免,1990年又新加了两个新的拥塞控制算法(即快重传和快恢复)来改进TCP的性能。
快速重传机制是什么呢?
考虑下面这种情况,在数据传送过程中,网络有可能不太稳定,个别报文段在网络中丢失了,但是实际上网络并没有发生拥塞。这样会导致发送方超时重传,误以为网络上发生了拥塞,由于有慢开始和拥塞避免机制,发送方错误的启动了慢开始算法,并且把拥塞窗口cwnd又设置为最小值1,因为降低了传输效率。
为解决这个问题,快重传要求接收方在收到一个失序的报文段后立即发出重复确认,为的是让发送方知道有一个报文丢失了,快速重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方还没有接收到的报文段,而不必继续等待设置的重传计时器时间到期。
4. 快恢复算法
快恢复算法适合快重传算法配合使用的
(1)当发送方连续收到三个重复确认的时候,执行“乘法减小”算法,将ssthresh门限减半(为了预防网络发生拥塞),但是接下来不执行慢开始算法,因为如果网络发生拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。
(2)此时不会执行慢开始算法,而是将拥塞窗口cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,让cwnd缓慢变大。