📄 一句话概括
TCP 头里 ACK 号与窗口字段搭同一辆车——确认与报余量合并成一次往返,省一半的包。
📝 本节和前面几节的关系
2.3.3 的 ACK 与 2.3.5 的窗口是两件事;本篇讲它们的合体。
一、一包两用
每次回 ACK 时顺手带上最新窗口值—— 对账(收到哪了)与通告(还能收多少)一次说清。
二、为什么值得合并
分开发要双倍报文;合起来只多 2 字节(窗口字段)。 小设计大收益——协议设计的品味所在。
三、动手 Demo:ACK 和窗口搭一辆车
一个报文里的两笔账:
for f, c, u in [('ACK 号','b+2920','对账:收到哪了'),
('窗口','5840','余量:还能收多少')]:
print('%-7s %-8s %s' % (f, c, u))
实跑输出:
--------------------------------------------------------------------
ACK 和窗口搭一辆车
--------------------------------------------------------------------
回 ACK 顺便报窗口,一条包两件事:
报文字段 内容 作用
---------------------------------------------
ACK 号 b+2920 对账:收到哪了
窗口 5840 对账之外:还能收多少
---------------------------------------------
所以【确认】和【报余量】合并成一次往返——
省一半的包,这是 TCP 效率的巧劲之一。
对照 1.4.4【协议栈不问内容】:协议栈对账用头, HTTP 分界用体——同一趟车两层分工。
30 秒实验
- Wireshark 里同一包同时看 ack 与 win 两个字段。
- 算算若 ACK 与窗口分开报,多花多少包。
- 想想还有哪些协议用【搭车】设计(如 HTTP 头与体)。
常见误区
- 以为 ACK 包只报确认——它还带窗口。
- 以为合并是优化可选——TCP 头设计即如此。
自测三问(点开对答案)
1. ACK 报文里搭车的是什么? —— 窗口字段。 2. 合并省了什么? —— 一半的往返报文。 3. 窗口字段收缩到 0 会怎样? —— 发送方暂停,等新通告。- ☐ 下一节(2.3.7 接收HTTP响应消息)
相关笔记
- 使用窗口有效管理ACK号 —— 窗口本体
- 接收HTTP响应消息 —— 收方视角
- 🔌 网络是怎样连接的 · 索引