一文带你搞定TCP拥塞控制 tcp拥塞控制技术
摘要
- 拥塞控制
- 慢启动
- 拥塞避免
- 拥塞发生
- 快速恢复
拥塞控制
什么是拥塞控制?
计算机网络是共享的,流量控制避免的是发送方填满接收方的空闲空间,而拥塞控制是避免发送方填满整个网络。
没有拥塞控制网络会发生什么?
当网络极度拥堵时,如果没有拥塞控制,发送方会继续发送大量的网络数据包,而这些数据包因为网络阻塞而延时、丢失,触发了TCP重传,重传使得网络更加阻塞,整个网络将会陷入不可用的状态。
什么是拥塞窗口?
拥塞窗口(cwnd)是发送方维护的一个状态变量,它会根据网络情况动态调节。
之前发送窗口约等于接收窗口,但在拥塞窗口加入后,发送窗口=min(拥塞窗口, 接收窗口)。
拥塞窗口的变化规则
- 只要网络中没有出现阻塞,窗口就会增大
- 网络中出现阻塞,窗口就会减小
发送方如何判定网络出现阻塞?
发送方在规定时间内没有收到ACK报文(也就是触发了超时重传)。
拥塞控制算法有几种?
- 慢启动
- 拥塞避免
- 拥塞发生
- 快速恢复
慢启动
慢启动的规则就是当发送方收到一个ACK,拥塞窗口的大小就会加1。
上图中假定发送窗口和拥塞窗口相等:
- 连接建立完成后,拥塞窗口cwnd为1,表示可以发送一个MSS的数据
- 当发送方收到一个ACK报文以后,拥塞窗口cwnd增加1变为2,发送方一次可以发送两个MSS的数据
- 当收到2个ACK报文以后,拥塞窗口cwnd增加2变为4,此时发送方一次可以发送4个MSS的数据
- 当收到4个ACK报文以后,拥塞窗口cwnd增加4变为8,此时能够发送8个MSS的数据
慢启动算法的发报个数呈指数级增长。
慢启动算法何时停止?
慢启动算法中有一个慢启动门限ssthresh(slow start threshold)的状态变量:
- 当拥塞窗口cwnd < ssthresh时,使用慢启动算法
- 当拥塞窗口cwnd >= ssthresh时,使用拥塞避免算法
一般来说,ssthresh的大小为65535字节。
拥塞避免
拥塞避免算法的规则是:每收到一个ACK报文,拥塞窗口cwnd增加1/cwnd。
上图中进入拥塞避免算法以后,第8个到来的ACK会增加1/cwnd,也就是增加1个变为9,最终可以发送9个MSS的数据。
通过上图可以看出,拥塞避免算法拥塞窗口还是增长的,只不过增长速度由指数变为了线性。
拥塞避免算法何时停止?
窗口一直在增长,网络会渐渐开始变得阻塞,网络中逐渐出现延时、丢包现象,导致TCP发生重传,此时就会进入拥塞发生阶段。
拥塞发生
TCP重传的机制大类主要有两种:
- 超时重传
- 快速重传
上述两种重传使用的拥塞发生算法也不相同。
超时重传拥塞发生
超时重传拥塞发生以后,ssthresh和cwnd会发生变化:
- ssthresh(慢启动门阀)设置为cwnd/2
- cwnd(拥塞窗口)重置为1
上图中可以看出超时重传拥塞发生时,可发送的数据包将会出现一个断崖式的下跌,这很容导致发送方卡顿。
快速重传拥塞发生
快速重传会在收到相同的3个ACK包时发生,发送端可以快速重传,不必在等待超时。这种情况下ssthresh和cwnd会发生以下变化:
- cwnd(拥塞窗口) = cwnd/2,拥塞窗口减少为一半
- ssthresh = cwnd
- 进入快速恢复算法
快速恢复
上图中可以看出,进入快速恢复前,ssthresh和cwnd的值已被更新。进入快速恢复以后:
- 拥塞窗口cwnd = ssthresh + 3(表示有三个数据包被收到)
- 重传丢失的数据包
- 如果收到的ACK是重复的,cwnd增加1
- 如果收到新数据的ACK,把拥塞窗口设置为第1步中ssthresh的值,因为ACK已经确认了新数据,快速恢复过程可以结束,可以再次进入拥塞避免阶段
快速恢复并没有出现断崖式下跌,可以发送的数据包依然在比较高的值,保持线性增长。