其他部分没什么好说的,发送端会在EFS < cwnd时发送信的数据,而同时,这又会使得EFS = cwnd
TCP New Reno
根据Reno的描述,TCP发送端会在收到3个重复的ACK时进行快速重传和快速恢复,但还有有一个问题,重复的ACK背后可能不仅仅是一个包丢了!如果是多个包丢了,即使发送端快速重传了丢失的第一个包,进入快速恢复,那么后面也会收到接收端发出的多个请求其他丢失的包的重复ACK!这个时候?发送端需要再累计到3个重复的ACK才能重传!
问题出在哪里?发送端不能重收到的重复ACK中获得更多的丢包信息!它只知道第一个被丢弃的报文,后面还有多少被丢弃了?完全不知道!也许使用SACK(参考RFC6675)这就不是问题,但这需要两端都支持SACK 。对于不支持SACK的场景,TCP需要更灵活!
RFC6582中描述的New Reno算法,在Reno中的基础上,引入了一个新的变量recover,当进入快速恢复状态时(收到3个重复的ACK[a]),将recover设置为已经发送的最后的报文的序号 。如果之后收到的新的ACK[b]序号b不超过recover,就说明这还是一个丢包引起的ACK !这种ACK在标准中也称之为部分应答(partial acknowledgments), 这时发送端就不等了,立即重传丢失的报文 。

文章插图
?

文章插图
编辑
TCP在发送报文后,如果没有收到对端应答,那么在重传定时器超时后会触发重传,超时时间遵循二进制退避原则,也就是{1,2,4,8,16}这样成倍地扩大超时时间 。退避是因为TCP认为丢包意味着网络有拥塞,为了不加重网络的拥塞,TCP选择等待更长的时间再进行重传 。这和CSMA/CD中的二进制退避算法如出一辙 。
网络中的网络设备(路由器、交换机)在收到了超过队列限制的报文后,后续的报文会被丢弃 。从TCP采用的二进制退避算来看,TCP绝对算得上是网络里的谦谦君子了,它信守的规则是:既然已经堵了,我就等一会儿再发,如果还堵,我就再多等翻倍的时间!
对整个网络来说,这的确是减轻负担的好办法 。要知道,在发送窗口已满的情况下,指数退避一次,意味着单位时间内发送的报文变成了原来的1/2,再退避一次,就只有原来的1/4!就像是汽车限号出行,单双号限行不好用,我就规定一辆车只能在4天中开1天...
But, TCP真的需要如此克制自己吗?,换个说法,为什么TCP一定要x2退避?难道重传定时器超时时间不能线性增大(每次增加X秒),或者乘以一个更小的系数(比如x1.5) ? 我们可以从CSMA/CD找到灵感 。
【图解丨TCP拥塞控制之基础】CSMA/CD使用x2的原因很好理解,共享介质中的每个节点并不知道其他还有多少节点,使用x2退避就是利用二分法快速找到让整个系统稳定运行的时隙分配方案!
举个例子,假设系统中有4个节点发包速率相同,那么最终的稳定分配方案自然就是将一段时间分为4份,每个节点占用1个时隙 。如果此时又加入4个相同的节点 。那么显然,所有的8个节点都会发包冲突 。如何才能不冲突呢?当然是分配给每个节点的时间再减小一半!当然这里举的例子节点都是2的整数幂 。如果不是呢?此时2进制退避依然能很快地达到稳定,也许这个时候的时隙分配方案不是最合理的,但是正如前面说的,每个节点并不知道其他还有多少节点,对单个节点来说,二进制退避是最快速找到让每个节点都正常工作的方案!

文章插图
?

文章插图
编辑
二进制退避方案中隐含了对公平性的考虑,它是站在整个网络的角度,而不是其中某一台主机!
但对一台特定的主机,不遵守这个退避规则显然好处更多...比如使用固定的重传定时器时间 。在这种网络中,没有拥塞时大家相安无事,一旦出现了拥塞,那么不退避的主机理论上就能发出更多的报文!

文章插图
?

文章插图
编辑
当然,这似乎牺牲了其他遵守规则主机的利益,它们的重传次数会增加 。那么,如果大家都不遵守呢?结果就是大家的重传次数都增加了,拥塞甚至比大家都遵守还要糟糕,因为网络上的设备丢的包更多了!
推荐阅读
- 图文并茂,讲解TCP和UDP协议的原理以及区别
- KET每日一词丨Sheet sheet是什么意思
- 技嘉主板BIOS设置图解教程 技嘉主板bios设置
- 杨桃的正确吃法图解 杨桃怎么吃
- 小说三要素关系图解 小说三要素
- 人参果的正确吃法图解 人参果的功效与作用
- 实用倒桩技巧“几进几退” 倒桩技巧图解
- 手把手教你在netty中使用TCP协议请求DNS服务器
- 扭力扳手使用方法图解与注意事项 扭力扳手怎么用
- 这份小区健身器材使用攻略请收好 小区健身器材使用图解
