这是理想的情况! 实际情况是A并不知道M和N有多大(或者说有什么关系),它只知道当cwnd超过M + N时会出丢包!于是我们折中地假定M = N,所以当cwnd = 2N时是丢包的临界点,为了解除阻塞,让cwnd = cwnd / 2 = N就可以解除阻塞3!

文章插图
所以,cwnd的变化趋势就像上面这样,图中上方的红色曲线表示出现丢包 。这样的稳定状态也称为拥塞避免阶段(congestion-avoidance phase)
现实算法实现中,拥塞避免阶段的cwnd是在收到每个ACK时更新的:cwnd += 1/cwnd,如果认真算,会发现这比整窗更新cwnd += 1要稍微少一点!
注3:后面会提到,Tahoe在此时会将cwnd先设置为1,然后再迅速恢复到cwnd / 2
Tahoe 慢启动 (Slow Start)
Tahoe需要为选定一个cwnd初始值,但是发送端并不知道多大的cwnd才合适 。所以只能从1开始4,如果这个时候就开始加性增,那就太慢了,比如假设一个连接会发送5050个MSS大小的报文,按照加性增加,需要100个RTT才能传输完成(1+2+3+...+100=5050) 。因此,Tahoe和Reno使用一种称为慢启动的算法迅速提高cwnd 。也就是只要没有丢包,每发送一个整窗的数据,cwnd = 2 X cwnd 。换句话说,在慢启动阶段(slow-start phase),当发送端每收到一个ACK时,就让cwnd = cwnd + 1

文章插图
?
注4RFC 2581 已经允许cwnd的初始值最大为2, RFC 3390 已经允许cwnd的初始值最大为4, RFC 6928已经允许cwnd的初始值最大为10
那么,慢启动阶段何时停止?或者说什么时候进入前面的拥塞避免阶段 ? Tahoe算法定义了一个慢启动阈值(slow-start threshold)变量,在cwnd < ssthresh时,TCP处于慢启动阶段,在cwnd > ssthresh后,TCP处于拥塞避免阶段 。
ssthreshold的初始值一个非常大的值 。连接建立后cwnd以指数增加,直到出现丢包后,慢启动阈值将被设置为 cwnd / 2 。同时cwnd被设置为1,重新开始慢启动过程 。这个过程如下图所示, 可以看到,慢启动可是一点也不慢 。

文章插图
?
Tahoe 快速重传 (Fast Retransmit)
现实的网络网络环境拓扑可能十分复杂,即使是同一个TCP连接的报文,也有可能由于诸如等价路由等因素被路由器转发到不同的路径,于是,在接收端就可能出现报文的乱序到达,甚至丢包!举个例子,发送端发送了数据DATA[1]、DATA[2]、……、DATA[8],但由于某些因素,DATA[2]在传输过程中被丢了,接收端只收到另外7个报文,它会连续回复多次 ACK[1](请求发送端发送DATA[2]) 。这个时候,发送端还需要等待DATA[2]的回复超时(2个RTT)吗?
快速重传的策略是,不等了!挡发送端收到第3个重复的ACK[1]时(也就是第4个ACK[1]),它要马上重传DATA[2],然后进入慢启动阶段,设置ssthresh = cwnd / 2 , cwnd = 1.

文章插图
?
如上图所示,其中cwnd的初始值为8,当发送端收到第3个重复的ACK[1]时,迅速进入慢启动阶段,之后当再收到ACK[1]时,由于cwnd = 1只有1,因此并不会发送新的报文
Reno 快速恢复(Fast Recovery)
在快速重传中,当出现报文乱序丢包后,拥塞窗口cwnd变为1,由于该限制,在丢失的数据包被应答之前,没有办法发送新的数据包 。这样大大降低了网络的吞吐量 。针对这个问题,TCP Reno在TCP Tahoe的基础上增加了快速恢复(Fast Recovery) 。
快速恢复的策略是当收到第3个重复的ACK后,快速重传丢失的包,然后
- 设置 sshthresh = cwnd / 2
- 设置 cwnd = cwnd /2
还是以上面的例子为例

文章插图
?
与快速重传中不同的是,发送端在收到第3个重复的ACK后,cwnd变为5,EFS设置为7
这里EFS表示发送端认为的正在向对端发送的包(Estimated FlightSize),或者说正在链路上(in flight)的包 。一般情况下,EFS是与cwnd相等的 。但在快速恢复的时候,就不同了 。假设拥塞避免阶段时cwnd = EFS = N,在启动快速恢复时,收到了3个重复的ACK,注意,这3个ACK是不会占用网络资源的(因为它们已经被对端收到了),所以EFS = N - 3,而既然是出发了快速恢复,那么一定是有一个包没有到达,所以EFS = N - 4,然后,本端会快速重传一个报文,EFS = N - 3,这就是上面EFS设置为7的来源 。
推荐阅读
- 图文并茂,讲解TCP和UDP协议的原理以及区别
- KET每日一词丨Sheet sheet是什么意思
- 技嘉主板BIOS设置图解教程 技嘉主板bios设置
- 杨桃的正确吃法图解 杨桃怎么吃
- 小说三要素关系图解 小说三要素
- 人参果的正确吃法图解 人参果的功效与作用
- 实用倒桩技巧“几进几退” 倒桩技巧图解
- 手把手教你在netty中使用TCP协议请求DNS服务器
- 扭力扳手使用方法图解与注意事项 扭力扳手怎么用
- 这份小区健身器材使用攻略请收好 小区健身器材使用图解
