在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大....
加入了拥塞窗口的概念后,此时发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。
拥塞窗口?cwnd
?变化的规则:
cwnd
?就会增大;cwnd
?就减少;规则:当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。
这里假定拥塞窗口?cwnd
?和发送窗口?swnd
?相等,举个例子:
cwnd = 1
,表示可以传一个?MSS
?大小的数据。有一个叫慢启动门限?ssthresh
?(slow start threshold)状态变量。
cwnd
?<?ssthresh
?时,使用慢启动算法慢启动算法的变化过程如下图(假设ssthresh
?为?8
):
cwnd
?>=?ssthresh
?时,就会使用「拥塞避免算法」。接上前面的慢启动的栗子(假设?ssthresh
?为?8)
:
MSS
?大小的数据,变成了线性增长。?可以发现拥塞避免算法就是将原本慢启动算法的指数增长变成了线性增长,还是增长阶段,但是增长速度缓慢了一些。
就这么一直增长着后,网络就会慢慢进入了拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。
当触发了重传机制,也就进入了「拥塞发生算法」。
当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:
这个时候,ssthresh 和 cwnd 的值会发生变化:
ssthresh
?设为?cwnd/2
,cwnd
?重置为?1
?(是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)ssthresh
?和?cwnd
?变化如下:
cwnd = cwnd/2
?,也就是设置为原来的一半;ssthresh = cwnd
;快速重传和快速恢复算法一般同时使用,快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像?RTO
?超时那么强烈。
正如前面所说,进入快速恢复之前,cwnd
?和?ssthresh
?已被更新了:
cwnd = cwnd/2
?,也就是设置为原来的一半;ssthresh = cwnd
;然后,进入快速恢复算法如下:
cwnd = ssthresh + 3
?( 3 的意思是确认有 3 个数据包被收到了);快速恢复算法的变化过程如下图: