TCP的零窗口探测(Zero Window Probing, ZWP)机制详解
字数 1140 2025-11-26 10:13:56
TCP的零窗口探测(Zero Window Probing, ZWP)机制详解
1. 问题背景:接收方窗口为0时的困境
TCP使用滑动窗口机制进行流量控制,接收方通过通告窗口(rwnd)告知发送方自己还能接收多少数据。当接收方缓冲区已满时,会发送rwnd=0的ACK,要求发送方暂停发送。但此时存在两个问题:
- 发送方如何知道接收方窗口何时恢复?
- 如果接收方后续的窗口更新ACK丢失,发送方将永远等待。
- 接收方窗口恢复后如何通知发送方?
- 若接收方没有数据要发送,则不会主动发送ACK(因为TCP采用捎带确认机制)。
2. 解决方案:零窗口探测机制
TCP通过持续定时器(Persist Timer) 实现零窗口探测:
- 当发送方收到rwnd=0的ACK时:
- 立即停止发送数据,并启动持续定时器(初始超时时间为TCP重传超时RTO)。
- 定时器超时后:
- 发送方向接收方发送一个1字节的探测报文段(称为ZWP包),强制接收方返回当前窗口大小。
- 若返回的rwnd仍为0,则重置持续定时器,下次超时时间指数退避(例如加倍,但有上限,如60秒)。
- 窗口恢复后的处理:
- 若探测报文返回的rwnd>0,发送方立即恢复数据发送。
3. 关键设计细节
- 探测包为什么是1字节?
- 即使接收方窗口为0,也必须接收至少1字节的紧急数据(RFC 1122要求),避免死锁。
- 若接收方缓冲区始终满,这1字节会被丢弃,但ACK会携带当前rwnd(可能仍为0)。
- 避免窗口更新ACK丢失:
- ZWP机制本质是发送方主动询问窗口状态,弥补了窗口更新ACK丢失的缺陷。
- 与重传定时器的区别:
- 重传定时器用于数据包丢失的重传,而持续定时器专用于解决零窗口死锁。
4. 实例分析
假设发送方发送数据至序列号1000时,接收方返回ACK=1001, rwnd=0:
- 发送方暂停发送,启动持续定时器(假设RTO=1秒)。
- 1秒后,发送方发送序列号为1001的1字节探测包。
- 接收方返回
ACK=1001, rwnd=0(窗口未恢复)。 - 发送方重置持续定时器为2秒,继续等待。
- 若接收方缓冲区空闲后,窗口更新ACK丢失,发送方会在2秒后再次探测,最终收到
rwnd>0的ACK。
5. 优化与注意事项
- 指数退避上限:防止定时器时间过长(如Linux默认上限为60秒)。
- 与糊涂窗口综合征(SWS)的关系:
- ZWP可能触发接收方通告小窗口,需结合SWS避免机制(如接收方等待窗口足够大时才更新rwnd)。
- Wireshark抓包标识:零窗口探测包通常标记为
[TCP ZeroWindowProbe]。
通过这一机制,TCP在流量控制中实现了对零窗口状态的可靠感知与恢复,确保了连接的高可用性。