在文章《【技术】TCP 的那些事 | 慢启动 》中 讲到,慢启动算法的拥塞窗口大小CWS(Congestion Window Size )有个上限值SSThresh(Slow Start Threshold),当CWS >= SSThresh时,就会进入“拥塞避免”阶段。一般来说SSThresh的值是65535字节,当CWS达到这个值时后,CWS的更新算法如下:
1. 收到一个ACK时,CWS = CWS + 1/CWS
2. 当每过一个RTT时,CWS =CWS + 1
这样就可以避免拥塞窗口增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。
Note:对于收到ACK时CWS的更新算法也有其他值,如:
CWS= CWS+ 1/CWS + MSS/8
当CWS >= SSThresh时就进入拥塞避免阶段。
拥塞避免阶段的CWS的变化如图1所示:
图1 拥塞避免阶段CWS变化示意图
进入拥塞避免阶段后,网络依然会拥塞。如果进入拥塞状态,网络发生丢包,那么有两种处理机制:
1. 等到RTO超时,重传数据包
SSThresh及CWS的更新过程如下:
SSThresh = CWS / 2
CWS = 1
随后进入慢启动过程
2. 使用快速重传(Fast Retransmit):收到3个Duplicate ACK时就开启重传
TCP Tahoe的实现和RTO超时一样;
TCP Reno的实现是:
CWS = CWS /2
SSThresh = CWS
进入快速恢复算法(Fast Recovery,见后续文章《【技术】TCP 的那些事 | 快速恢复》)
图2 快速重传算法示意图
当RTO超时后,SSThresh会变成CWS的一半,而CWS初始化为1,随后进入慢启动阶段,CWS又很快地以指数级增涨爬到这个地方时,就会成慢慢的线性增涨。我们可以看到,TCP是怎么通过这种强烈地震荡快速而小心得找到网站流量的平衡点的。
图3 拥塞避免CWS变化示意图
(图片来源网络)
其中,图3中的cwnd与上文CWS相同,ssthresh和SSThresh相同。
参考资料
1.http://www.mathcs.emory.edu/~cheung/Courses/558a/Syllabus/6-transport/TCP.html