拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TCP滑动窗口与拥塞控制是什么?从流量控制到网络稳定性的完整解析

TCP滑动窗口与拥塞控制是什么?从流量控制到网络稳定性的完整解析

前言

TCP是互联网上使用最广泛的传输层协议。它提供可靠传输、按序交付、流量控制、拥塞控制等能力。其中,滑动窗口和拥塞控制是两个容易被混淆的概念:它们都涉及"窗口",都影响发送速率,但解决的问题完全不同。

这篇文章把这两个机制拆开来讲清楚:滑动窗口解决的是"接收方能不能收得下",拥塞控制解决的是"网络能不能承受得住"。理解这个分工,就理解了TCP为什么能在不可靠的网络上实现可靠传输。

一、为什么需要滑动窗口

1.1 停止等待协议的效率问题

最基础的可靠传输方式是"停止等待":发送方发一个数据包,等待接收方确认(ACK),收到确认后再发下一个。

这种方式逻辑简单,但效率极低。假设发送方和接收方之间的往返时间(RTT)是50毫秒,每个数据包大小为1KB,那么理论最大吞吐量只有:

text

1KB / 0.05s = 20KB/s

链路带宽可能远高于这个数值,但停止等待协议无法充分利用。原因在于:发送方大部分时间都在等待确认,链路处于空闲状态。

1.2 滑动窗口的基本思路

滑动窗口的核心思路是:允许发送方在收到确认之前,连续发送多个数据包。

发送方维护一个"窗口",窗口内的数据可以连续发送而不需要等待确认。每收到一个确认,窗口向前滑动,新的数据可以进入窗口并被发送。

这样,发送方不必每发一个包就停下来等确认,链路的利用率大幅提升。

二、滑动窗口的工作机制

2.1 发送窗口与接收窗口

TCP连接的两端各维护一个窗口:

发送窗口:发送方可以连续发送而不需要等待确认的数据量。窗口大小由接收方通告的接收窗口(rwnd)和拥塞窗口(cwnd)共同决定,取两者中的较小值。

接收窗口:接收方当前能够接收的数据量。接收方通过TCP头部的窗口字段,将自己的接收窗口大小告知发送方。

2.2 窗口的滑动过程

假设发送窗口大小为4个数据段:

  1. 发送方连续发送段1、2、3、4

  2. 接收方收到段1,返回ACK确认段1

  3. 发送方收到ACK后,窗口向前滑动一个位置,段5进入窗口并被发送

  4. 接收方收到段2,返回ACK确认段2

  5. 发送方窗口再次滑动,段6进入窗口并被发送

这个过程持续进行,窗口不断向前滑动,数据持续发送。

2.3 接收窗口的动态调整

接收窗口的大小不是固定的。接收方的缓冲区可能被应用程序读取数据的速度影响:

  • 如果应用程序读取数据快,接收缓冲区空闲多,接收窗口可以保持较大

  • 如果应用程序读取数据慢,接收缓冲区被占满,接收窗口会减小

  • 如果接收缓冲区完全占满,接收窗口变为0,发送方必须停止发送

当接收窗口变为0时,发送方会启动零窗口探测:定期发送探测报文,询问接收方窗口是否已恢复。这防止了双方陷入永久等待。

2.4 流量控制的作用

滑动窗口实现的流量控制,核心目标是防止发送方发送速度超过接收方的处理能力。接收方通过动态调整窗口大小,控制发送方的发送速率,避免接收缓冲区溢出导致数据丢失。

三、为什么需要拥塞控制

3.1 流量控制解决不了的问题

滑动窗口解决了接收方的处理能力问题,但没有解决网络本身的问题。

如果网络中的路由器或链路出现拥塞,数据包会在路由器队列中排队,延迟增加。当队列满时,路由器会丢弃数据包。发送方检测到丢包后重传,但重传会进一步加重网络负担,形成恶性循环——这就是拥塞崩溃。

流量控制只关注接收方,不关注网络中间状态。如果发送方和接收方之间的网络出现拥塞,即使接收方窗口很大,发送方也不应该继续高速发送。

3.2 拥塞控制的核心思路

拥塞控制的目标是:在没有明确网络状态反馈的情况下,通过探测和调整,找到一个不会导致网络拥塞的发送速率。

TCP拥塞控制通过维护一个拥塞窗口(cwnd)来实现。发送方实际可以发送的数据量,取接收窗口和拥塞窗口中的较小值:

text

实际发送窗口 = min(接收窗口rwnd, 拥塞窗口cwnd)

拥塞窗口由发送方独立维护,根据网络状况动态调整。

四、拥塞控制的四个核心算法

TCP拥塞控制包含四个相互配合的算法:慢启动、拥塞避免、快速重传、快速恢复。

4.1 慢启动

连接建立初期,发送方不知道网络的承载能力,因此从一个较小的拥塞窗口开始探测。

慢启动的规则是:每收到一个ACK,拥塞窗口增加一个MSS(最大报文段长度)。这意味着拥塞窗口随RTT呈指数增长:1、2、4、8、16……

"慢"指的是起点低,而不是增长速度慢。指数增长使发送方能够快速探测到网络的可用带宽。

慢启动设置了一个慢启动阈值(ssthresh)。当拥塞窗口达到ssthresh时,慢启动结束,进入拥塞避免阶段。

4.2 拥塞避免

进入拥塞避免阶段后,拥塞窗口的增长方式从指数变为线性:每个RTT,拥塞窗口增加一个MSS。

线性增长使发送方缓慢逼近网络的承载极限,避免过快增长导致拥塞。这个阶段持续到检测到丢包为止。

4.3 快速重传

当接收方收到乱序的数据段时,会立即发送重复ACK,告知发送方某个数据段未到达。

如果发送方连续收到三个重复ACK,就判断该数据段丢失,立即重传,而不需要等待超时计时器到期。这显著缩短了丢包恢复时间。

4.4 快速恢复

快速重传后,发送方进入快速恢复阶段:

  • 将ssthresh设为当前拥塞窗口的一半

  • 将拥塞窗口设为ssthresh + 3(3表示已收到的三个重复ACK)

  • 每收到一个重复ACK,拥塞窗口增加1

  • 收到新数据的ACK后,拥塞窗口设为ssthresh,进入拥塞避免

快速恢复避免了慢启动的重新开始,使发送方能够更快恢复到丢包前的发送速率。

五、拥塞控制的演进

5.1 TCP Tahoe与TCP Reno

早期的TCP Tahoe在检测到丢包时,无论超时还是快速重传,都会将拥塞窗口重置为1,重新进入慢启动。

TCP Reno引入了快速恢复机制,在快速重传后不重置窗口,而是从ssthresh继续。这是目前大多数操作系统默认支持的版本。

5.2 TCP NewReno

TCP Reno在多个数据包丢失的场景下存在局限。NewReno改进了快速恢复的处理逻辑,能够在一个窗口内多个丢包时更准确地恢复。

5.3 TCP CUBIC

CUBIC是目前Linux系统的默认拥塞控制算法。它使用三次函数代替线性增长,使窗口增长曲线更平滑,在高带宽、长距离网络(高BDP场景)中表现更好。

5.4 BBR

BBR(Bottleneck Bandwidth and Round-trip propagation time)是Google提出的拥塞控制算法。它不依赖丢包作为拥塞信号,而是通过测量瓶颈带宽和最小RTT来构建发送模型。BBR在长距离、高丢包的网络环境中表现突出。

六、滑动窗口与拥塞控制的对比

对比维度滑动窗口拥塞控制
解决的问题接收方处理能力网络承载能力
控制依据接收方通告的接收窗口发送方维护的拥塞窗口
反馈来源接收方的窗口字段ACK、丢包、RTT变化
调整方向接收方主动调整发送方主动探测
目标防止接收缓冲区溢出防止网络拥塞崩溃
实际发送窗口min(rwnd, cwnd)min(rwnd, cwnd)

两者协同工作:滑动窗口确保发送方不超过接收方的处理能力,拥塞控制确保发送方不超过网络的承载能力。实际发送窗口取两者中的较小值,任何一方成为瓶颈时,发送速率都会被限制。

七、总结

TCP的可靠传输依赖两个核心机制:

滑动窗口实现了流量控制。发送方可以在收到确认前连续发送多个数据段,窗口大小由接收方动态调整,防止接收缓冲区溢出。

拥塞控制实现了网络稳定性。发送方通过慢启动、拥塞避免、快速重传、快速恢复等算法,动态调整拥塞窗口,探测网络的可用带宽,避免因发送速率过快导致网络拥塞崩溃。

两者的关系可以概括为:滑动窗口管"接收方能不能收",拥塞控制管"网络能不能扛"。实际发送窗口取两者中的较小值,任何一方出现瓶颈,发送速率都会相应调整。理解这个分工,就理解了TCP为什么能在不可靠的网络上实现可靠传输。

返回列表