TCP滑动窗口机制
TCP滑动窗口机制
TCP 的滑动窗口机制(Sliding Window)是实现高效传输 + 流量控制 + 拥塞控制基础的核心机制之一。可以把它理解为:发送方不用等每个包确认,就可以连续发送多个数据包,但数量受到窗口大小限制。
一、为什么需要滑动窗口?
如果没有滑动窗口,TCP 只能这样:
1 | 发一个包 → 等ACK → 再发一个 |
问题:
- RTT(往返时间)一高 → 吞吐量极低
- 网络带宽利用率非常差
滑动窗口解决:允许“批量发送 + 批量确认”
二、核心概念
2.1 窗口(Window)
窗口本质是一个缓冲区范围,表示:
发送方在未收到ACK之前,最多可以发送多少字节的数据
2.2 发送窗口(Send Window)
发送窗口包含三部分:
1 | | 已发送已确认 | 已发送未确认 | 可以发送 | |
- 已发送已确认:可以丢弃
- 已发送未确认:等待 ACK
- 可以发送:窗口允许范围内的数据
2.3 接收窗口(Receive Window)
接收方通过 TCP 头部字段:
1 | Window Size |
告诉发送方:“我还能接收多少数据”
这就是流量控制(Flow Control)
三、滑动窗口是如何“滑动”的?
举个例子:
初始状态(窗口大小 = 3):
1 | [1][2][3] 4 5 6 7 |
发送 1,2,3 后:
1 | (1)(2)(3) 4 5 6 7 |
收到 ACK=2(表示 1,2 已确认):
1 | ↓窗口右移 |
窗口向右“滑动”,继续发送 4、5
四、滑动窗口的三个关键变量
4.1 snd_una
- 最早未确认的数据序号
4.2 snd_nxt
- 下一个要发送的序号
4.3 snd_wnd
- 发送窗口大小
关系:
1 | 已发送未确认区间:[snd_una, snd_nxt) |

五、滑动窗口的两大作用
5.1 提高吞吐量(核心作用)
允许:
1 | 连续发送多个包(pipeline) |
而不是停等协议。
5.2 流量控制(Flow Control)
接收方控制发送方速度:
- 接收窗口大 → 发快一点
- 接收窗口小 → 慢一点
- 接收窗口 = 0 → 停止发送(窗口关闭)
六、零窗口问题(Zero Window)
如果接收方返回:
1 | Window Size = 0 |
发送方就不能发数据了
但会启动:
零窗口探测(Persist Timer)
定期发送小包询问:“你现在能收了吗?”
七、滑动窗口 vs 拥塞窗口
很多面试官会考
| 类型 | 控制方 | 作用 |
|---|---|---|
| 接收窗口 rwnd | 接收方 | 流量控制 |
| 拥塞窗口 cwnd | 发送方(网络) | 拥塞控制 |
最终发送窗口:
1 | 实际发送窗口 = min(rwnd, cwnd) |
八、常见面试延伸问题
8.1 为什么窗口是“字节”而不是“包”?
TCP 是面向字节流的协议
2:窗口太大有什么问题?
- 接收方处理不过来
- 网络可能拥塞
3:窗口太小?
- 吞吐量低
- 带宽浪费
九、一句话总结
TCP 滑动窗口 = 在可控范围内连续发送数据 + 动态调整发送速率的机制