Skip to content

TCP 流量控制

考情分析

TCP 流量控制在 408 中属于中高频考点,常与拥塞控制结合出题。选择题考查流量控制与拥塞控制的区别、零窗口的处理方式;大题可能要求分析窗口变化过程。

考频:★★★★

流量控制的基本概念

流量控制要解决的问题很直接:发送方发得太快,接收方来不及处理

如果发送方的发送速率远大于接收方的处理速率,接收方的缓冲区就会溢出,数据就会丢失。流量控制就是让发送方的发送速率不要超过接收方的处理能力。

TCP 使用滑动窗口机制来实现流量控制。接收方通过 TCP 首部的窗口字段告知发送方自己当前的接收窗口大小 rwnd(receiver window),发送方据此调整发送窗口。

接收窗口 rwnd

接收方根据自己的缓冲区空闲空间来设置 rwnd 的值,并在每一个 ACK 报文段中将 rwnd 通告给发送方。

rwnd=接收缓冲区大小已接收但未被应用层读取的数据量

发送方的发送窗口取 rwnd 和 cwnd 的较小值:

发送窗口=min(cwnd,rwnd)

如果只考虑流量控制(不考虑拥塞控制),发送窗口 = rwnd。

窗口动态调整过程

通过一个具体的例子来理解窗口的动态调整。

假设 A 向 B 发送数据,B 的接收缓冲区大小为 400 字节。

步骤A 的操作B 的操作B 通告的 rwnd
1发送 100 字节 (seq=1)收到,缓冲区剩 300rwnd=300
2发送 100 字节 (seq=101)收到,缓冲区剩 200rwnd=200
3发送 100 字节 (seq=201)收到,缓冲区剩 100rwnd=100
4应用层读走 200 字节,缓冲区剩 300rwnd=300
5发送 100 字节 (seq=301)收到,缓冲区剩 200rwnd=200

可以看到,rwnd 不是单调递减的。当接收方的应用层从缓冲区读取数据后,rwnd 会增大。

零窗口问题

当接收方的缓冲区满了,rwnd = 0,接收方会发送一个零窗口通告。发送方收到后必须停止发送数据。

问题来了:如果接收方后来腾出了空间,发送了一个 rwnd > 0 的通告,但这个通告报文段丢失了,那就死锁了——A 等 B 说可以发了,B 等 A 发数据过来。

持续计时器

TCP 为了解决这个问题,设置了持续计时器(Persistence Timer)。

工作方式:

  1. 当发送方收到零窗口通告后,启动持续计时器
  2. 计时器到期时,发送方发送一个零窗口探测报文段(仅携带 1 字节数据)
  3. 接收方收到探测报文后,回复当前的窗口大小
  4. 如果窗口仍为 0,发送方重置计时器继续等待
  5. 如果窗口不为 0,发送方恢复正常发送

零窗口探测报文段虽然只有 1 字节,但它打破了死锁的可能性。

Nagle 算法

Nagle 算法解决的是小报文段过多的问题。如果应用层每次只产生 1 字节数据(比如 Telnet 的键盘输入),每个字节都单独发送的话,1 字节数据 + 20 字节 TCP 首部 + 20 字节 IP 首部 = 41 字节,开销比例极高。

Nagle 算法的规则:

  • 第一个小报文段立即发送
  • 后续的小数据先缓存起来,等到以下条件之一满足时再发送:
    • 收到前一个报文段的确认
    • 缓存的数据量达到 MSS

这样就把多个小数据合并成一个较大的报文段发送,减少了网络中小报文段的数量。

408 对 Nagle 算法的考查不深,知道它的作用和基本原理即可。

糊涂窗口综合症

糊涂窗口综合症(Silly Window Syndrome)是另一个和小报文段相关的问题,但它发生在接收方

场景:接收方的缓冲区几乎满了,应用层每次只读取很少的数据(比如 1 字节),然后接收方就通告一个很小的窗口(比如 rwnd=1),发送方据此发送一个很小的报文段。如此反复,网络中充满了低效的小报文段。

解决方案(Clark 方案):接收方不要在窗口刚腾出一点空间时就立刻通告。而是等到:

  • 缓冲区有足够大的空间(比如一半以上空闲),或者
  • 能容纳一个 MSS 大小的报文段

才发送窗口更新通告。在此之前,继续通告 rwnd=0。

流量控制与效率的权衡

流量控制本质上是一种端到端的速率匹配机制。它在保护接收方不被淹没的同时,也可能限制传输效率。

考虑这样一个场景:接收方的应用层读取数据很慢(比如正在做复杂的计算),rwnd 会逐渐缩小,发送方被迫降低发送速率。即使网络本身没有拥塞,发送方也发不快——因为瓶颈在接收方的处理能力。

在 408 的大题中,如果同时给了 rwnd 和 cwnd,发送窗口 = min(cwnd, rwnd)。需要判断哪个是瓶颈:

  • 如果 rwnd < cwnd:瓶颈在接收方(流量控制限制了发送速率)
  • 如果 cwnd < rwnd:瓶颈在网络(拥塞控制限制了发送速率)
  • 实际发送窗口总是取较小值

交互可视化

加载可视化中...

易错点

1. 流量控制和拥塞控制是两回事

流量控制是点对点的,防止发送方发得比接收方处理的快。拥塞控制是全局性的,防止网络过载。控制变量分别是 rwnd 和 cwnd。

2. 零窗口通告不是错误

零窗口是正常的流量控制行为,说明接收方缓冲区暂时满了。发送方收到后不是断开连接,而是启动持续计时器等待。

3. 持续计时器是发送方启动的

不是接收方。接收方只负责通告窗口大小,发送方负责在零窗口时主动探测。

4. rwnd 的单位是字节

TCP 首部窗口字段 16 位,表示的最大值是 65535 字节。如果需要更大的窗口,可以使用窗口缩放选项(Window Scale Option),这个选项在三次握手时协商。

5. 零窗口探测报文段也有重传计时器

如果零窗口探测报文段丢失了,发送方的持续计时器会再次超时,重新发送探测报文。这保证了即使探测报文丢失也不会永远死锁。

6. 发送窗口可能小于 rwnd

发送窗口 = min(cwnd, rwnd)。如果拥塞窗口 cwnd 比接收窗口 rwnd 小,那么发送窗口由拥塞控制决定,而不是流量控制。

高频考点清单

  • 流量控制的目的:防止发送方发得比接收方处理的快
  • rwnd 由接收方在每个 ACK 中通告
  • 发送窗口 = min(cwnd, rwnd)
  • 零窗口的处理:持续计时器 + 零窗口探测报文段
  • 流量控制 vs 拥塞控制的区别(作用范围、控制变量、触发条件)
  • Nagle 算法的作用(合并小报文段)
  • 糊涂窗口综合症及其解决方案

真题练习

相关真题(6题)

2026Q47综合题9分

TCP 综合题:拥塞窗口变化、发送窗口计算、四次挥手时间分析

2025Q38选择题2分

TCP 流量控制与拥塞控制:发送窗口取 rwnd 和 cwnd 较小值

2021Q40选择题2分

TCP 发送窗口计算:已发送未确认 200B + 可用窗口,序号范围 701~1000

2017Q39选择题2分

TCP 慢开始阶段窗口指数增长到目标值所需 RTT 数

2015Q39选择题2分

TCP 拥塞控制:发送窗口受接收窗口和拥塞窗口双重限制

2010Q39选择题2分

TCP 发送窗口与已发送未确认数据的关系