- 拥塞窗口
cwnd
重置为1 。 - 慢开始上门限值
ssthresh
减半 。
![【lwip】12-一文解决TCP原理](http://img.zhejianglong.com/231019/221S5DI-15.png)
文章插图
12.8.4.2 快速重传超时重传的拥塞发生算法过于激进的做法,这适合与真的发生拥塞时,但是有时候网络正常丢包,这不不是超时引起的重传,而是网络丢包引起的重传 。
当收到对端连续三次ACK同一个SEQ时 , 我们就能判断为发送了网络丢包,这时就不用等待超时,不用执行超时重传的拥塞算法了 , 而是执行快速重传的拥塞发生算法:
- 拥塞窗口
cwnd
设为原来的一半:cwnd /= 2
; - 慢开始上门限值
ssthresh = cwnd
;(cwnd为减半后的拥塞窗口) - 进入快恢复算法 。
因为快恢复算法认为,能收到三个ACK,说明网络还不是很差,没必要像RTO一样搞得那么僵 。
快恢复算法:
- 收到第3个重复ACK时,先执行快速重传算法,然后拥塞窗口
cwnd = ssthresh + 3
(3:每收到1个ACK,可以认为对端收到1次TCP包 , 网络上就少了1个TCP包,一个包最大为1个报文段 , 所以快恢复的拥塞窗口就追加3个报文段) 。 - 收到超过3个重复的ACK时,每次都会增大拥塞窗口:
cwnd += 1
。 - 当收到新的ACK后:
cwnd = ssthresh
。然后进入拥塞避免算法 。
![【lwip】12-一文解决TCP原理](http://img.zhejianglong.com/231019/221S540B-16.png)
文章插图
12.8.6 Nagle算法如果一个TCP报文每次只发送1个字节,这就产生了一些41字节长的分组:20字节的IP首部、20字节的TCP首部和1个字节的数据,利用率太低 。(IPV4)
解决方法就是RFC 896 [Nagle1984]中所建议的Nagle算法 。
nagle算法是提高传输效率,降低拥塞出现的可能 。
【【lwip】12-一文解决TCP原理】nagle算法: 尽可能组合更多数据合到同一个报文段中 。满足以下条件之一 , nagle算法都不会生效:
- 用户设置了
TF_NODELAY
标志 。(该标志表示关闭nagle算法) - 没有飞行中的数据,可以立即发送 。
- 报文段中还有FIN标记 , 可立即发送 。
- 未发送的报文段长度大于或大于一个MSS,也满足立即发送条件 。
- 发生超时 , 立即发送 。
所以就有了延迟确认这个算法 。
如果开启了延迟确认,在接收到TCP包后,等待一小段时间(Linux 上默认是 40ms、LWIP默认250ms),如果在这段时间内收到新的TCP包,则只需要在时间到达后确认一次即可 。
当然 , 遇到特殊情况可以不用等待时间到达,可以立即响应ACK:
- 收到乱序包 。
- 收到窗口外的TCP包 。
- 需要调整窗口 。
- 收到RST 。
- 发送的报文段中含有FIN 。
当然,在一些轻量的TCPIP协议栈中,并不会为每个报文都使用独立的超时计时,如LWIP,每个TCP控制块只有一个超时计时值 , 每收到一个新的ACK都会被清零重新计时,在RTO后都还没收到ACK,便会把UNACK队列中的所有数据都会回迁至UNSENT队列 。
12.9.2 坚持定时器坚持(persist)定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 。
先来了解下窗口探查 。
窗口探查(window probe):
当接收方TCP缓冲区没有剩余空间后 , 在ACK中会通知发送方window=0,此时发送方就暂停发送数据 。
当接收方TCP缓冲区又有空间后,会再次发送一个ACK , 告知其剩余缓冲区大小,可以接受新的数据包了 , 这个ACK叫做窗口更新 。
TCP接收方则等待新的数据包过来 。但是如果这个窗口更新的ACK丢失了,那么会出现两端互相等待:接收方等待新的数据包,因为他已经通知对端新的window大小了,而发送方则还在等待窗口更新 , 因为它还认为对端窗口为0 。
推荐阅读
- vulnhub靶场之DOUBLETROUBLE: 1
- 亚索怎么玩呢(亚索大招怎么才能释放)
- 如何打好亚索(亚索的打法技巧)
- 无期迷途钻石获取途径有哪些
- 传奇九层妖塔祖玛阁怎么走(传奇祖玛阁攻略)
- 【深入浅出 Yarn 架构与实现】2-4 Yarn 基础库 - 状态机库
- 【Azure API 管理】Azure APIM服务集成在内部虚拟网络后,在内部环境中打开APIM门户使用APIs中的TEST功能失败
- DNF里浓缩的异界精髓怎么获得(浓缩的异界精髓作用)
- 小孩沉迷手机网络游戏怎么办(儿童玩手机游戏沉迷怎么办)
- 带你了解NLP的词嵌入