窗口到底有多滑动?揭秘 TCP/IP 滑动窗口的工作原理
本文分享自华为云社区《窗口到底有多滑动?揭秘TCP/IP滑动窗口的工作原理》,作者: Lion Long。
当涉及网络性能优化和数据传输可靠性时,TCP/IP 滑动窗口是一个关键的技术。本文的摘要将深入揭示 TCP/IP 滑动窗口的工作原理,探讨其在确保数据准确性和实现高效通信方面的重要性。通过对滑动窗口大小、流控制和数据包确认机制的解析,我们将揭示如何通过优化窗口大小和流控制参数来提升网络性能。
一、TCP 报头
二、TCP 流量控制
一般来说,我们希望数据传输得更快;但如果发送方发送数据过快,接收方还没来得急接收数据,就会造成丢包现象。
流量控制就是让发送方控制发送速率,让接收方能及时接收数据。TCP 利用滑动窗口机制实现发送方的流量控制。
网络上进行数据传输的时候,需要考虑如何达到高效的收发数据。那么就需要考虑接收方可以接收多少网络包和网络上可以发送多少网络包的问题。
接收方通过发送数据出去的时候,同时告诉发送方我还能接收多少数据包。
要知道网络上数据传输的状态,可以通过计算往返时间。
2.1、持续计时器
TCP 为每一个连接设有一个持续计时器。只有 TCP 的一方收到对方的零窗口通知,就启动持续计时器;只要持续计时器超时,就放送一个零窗口探测报文,携带一字节的数据;而对方收到零窗口探测报文时,回复自己现有的接收窗口值。如果窗口大小依旧是零,那么收到报文的一方就重新启动持续计时器。
零窗口探测报文丢失是不是无法打破死锁?零窗口探测报文发送的时候也会启动重传计时器,不必担心零窗口探测报文丢失会无法打破死锁局面。
持续计时器是为了解决双方相互等待(A 等待 B 发送非零窗口的通知,B 等待 A 发送数据)而形成的死锁现象。这种现象一般发生在发送窗口大小数据包丢失时。
2.2、RTT
RTT,全称 Round Trip Time,即往返时间。由链路传播时间、末端系统处理时间、路由器缓存中排队和处理的时间组成。
Round Trip Time
对于 TCP 来说,路由器缓存中排队和处理的时间会随着网络拥塞程度辩护而变化。通过计算 RTT 可以反应网络拥塞程度,从而拥塞控制。
RTT
RTT 的计算公式:new_RTT = percent*pre_RTT+(1-percent)*RTT;
其中 percent 取值范围 0.8~0.9 ;pre_RTT 是上一次的 RTT,RTT 是本次 RTT。计算出来 new_RTT,如果 RTT 大于 new_RTT,那么就超时。
2.3、RTO
RTO,全称 Retransmission TimeOut,即重传超时时间。
超时之后 TCP 进入 Loss 状态,重传所有没有被确认的报文,同时进入慢启动的回复过程。
2.4、拥塞的定义
随着网络上的主机不断增加其发送速率,会使整个网络变得非常拥挤;这会导致网络经常出现丢包现象,使网络传输效率大幅度下降。
如果不对网络做拥塞控制,会降低整个网络的传输效率,直到吞吐量为 0,进入死锁。
拥塞
2.5、慢启动和拥塞控制
(1)一条 TCP 连接开始时,window size 被设置为 1 MSS(最大报文段大小)。
(2)TCP 发送方发送完发送窗口数据,并收到所有的确认,window size 以指数增长(以 2 的倍数进行翻倍),即慢启动阶段。
(3)window size 增长到一个慢启动的阈值 thresh,开始执行拥塞控制算法(window size 呈线性增长),进入拥塞控制阶段。
(4)随着 window size 增长,发送速率提高,出现网络拥塞,分组超时重传。
慢启动
拥塞控制
慢启动是指一开始向网络中发送的报文段少,而不是指拥塞窗口增长速度慢。
拥塞避免不是指完全能够避免拥塞,而是指在拥塞避免阶段将拥塞窗口控制为线性规律增长,使网络比较不容易出现拥塞。
2.6、快重传和快恢复
1990 增加新的拥塞控制算法:快重传和快恢复。用于改进 TCP 的性能。
有时候,个别报文会在网络中丢失,当实际上网络并没有发生拥塞,这将导致发送方超时重传并认为网络出现了拥塞;从而错误的启动慢启动算法,因此降低传输效率。为此,引入快重传算法,可以让发送方尽早知道个别报文段的丢失。
所谓快重传,就是发送方尽快的进行重传,而不是等超时计时器超时才重传。快重传可以使整个网络吞吐量提高约 20%。
发送方接收到 3 个重复确认,就知道只丢失了个别报文段,于是不启动慢启动算法,而是执行快恢复算法。
所谓快恢复,就是发送方将慢启动上限和拥塞窗口值调整为当前窗口的一半,开始执行拥塞避免算法。
三、滑动窗口
TCP 基于以字节为单位的滑动窗口来实现可靠传输。
滑动窗口需要考虑网络上能发多少以及接收方能接收多少;即窗口大小=min{接收方窗口,网络上可发送数据包大小};
两个指针,前指针指示已接收或已发送并确认的字节序,后指针指示不允许接收/发送的开始位置,两个指针之间就是可收发数据的窗口大小。
窗口大小是动态的,可以通过 RTT 计算。比如发 4K 到网络,出现拥塞,那么就将窗口逐渐减小。RTT 防抖,可以推算窗口大小。
四、思考
(1)接收方不 recv,发送方一直 send,send 的数据去哪里了??
这种情况接收方的缓冲区逐渐饱和,达到饱和时滑动窗口为 0,此时发送方还在 send,那么数据就会滞留在发送方的缓冲区,发送方缓冲区也会逐渐饱和,当发送方缓冲区无法再写入数据时,send 返回-1,告诉应用程序 IO 不可写。
(2)tcp 如何保证顺序?
不能保证接收序号是顺序的,只能保证应用程序取的时候是顺序的。适当延迟回复 ACK 可以提高 TCP 的传输效率,一般最多延迟 0.5 秒,否则可能会使重传计时器超时出现重传。
总结
TCP 通过以字节为单位的滑动窗口实现可靠传输。
TCP 进行流量控制时使用四个算法:慢启动、拥塞避免、快重传、快恢复。
滑动窗口是动态的,它的大小取接收端可接受窗口大小和网络可发送大小的最小值。比如一条公共路段和接收方的仓库,发送的货物多少取决于公路和仓库的最小值;公路很大但仓库很小,公路上运输再多的货物而仓库无法装载得下;仓库很大但公路较小,仓库就算能装再多的货物而公路只能运输少量的货物。
滑动窗口为 0 时,会开启持续计时器,用于探测接收方是否有空间接收数据,防止进入无休止的等待,即死锁。
详细的计算机网络知识,可以参看湖科大计算机网络视频。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/9b08fbc052340972441db1c0f】。文章转载请联系作者。
评论