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
2
[1][2][3] 4 5 6 7
↑窗口范围

发送 1,2,3 后:

1
(1)(2)(3) 4 5 6 7

收到 ACK=2(表示 1,2 已确认):

1
2
      ↓窗口右移
[3][4][5] 6 7

窗口向右“滑动”,继续发送 4、5

四、滑动窗口的三个关键变量

4.1 snd_una

  • 最早未确认的数据序号

4.2 snd_nxt

  • 下一个要发送的序号

4.3 snd_wnd

  • 发送窗口大小

关系:

1
2
已发送未确认区间:[snd_una, snd_nxt)
可发送区间:[snd_nxt, snd_una + snd_wnd)

五、滑动窗口的两大作用

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 滑动窗口 = 在可控范围内连续发送数据 + 动态调整发送速率的机制