零窗口代表什么
TCP 接收端把剩余接收缓冲大小写进每个包的通告窗口字段。缓冲被写满、应用来不及读取时,接收端通告窗口 0,发送端随即停止发送并转为周期性的窗口探测;应用读取释放缓冲后,接收端再发窗口更新恢复传输。用 tcpdump 直接读窗口字段为 0,就能把这类「卡顿」筛出来。
基本信息
| 适用平台 | Linux / macOS / BSD 上的 tcpdump |
|---|---|
| 语法 | tcp[14:2] = 0 [and 其他条件] |
| 偏移说明 | 按标准 20 字节 TCP 头定位窗口字段,tcpdump 会按实际头长修正 |
| 配合选项 | -nn 与 -ttt 看间隔,-c 限量 |
| 等价 Wireshark 过滤 | tcp.analysis.zero_window |
典型使用场景
- 吞吐突然掉到接近 0 时,判断是否为接收侧处理不过来
- 长连接业务出现周期性卡顿,观察零窗口出现的频率
- 评估应用读取逻辑或线程池是否需要调整
- 配合窗口探测与窗口更新确认恢复耗时
常用示例
常用示例
tcpdump -i eth0 -nn 'tcp[14:2] = 0' -c 20 # 抓零窗口通告
tcpdump -i eth0 -nn 'tcp[14:2] = 0 and host 10.0.0.9' # 限定对端
tcpdump -i eth0 -nn -ttt 'tcp[14:2] = 0 or tcp[14:2] < 200' -c 30 # 同时观察小窗口
tcpdump -nn -r slow.pcap 'tcp[14:2] = 0' | wc -l # 离线统计次数配套信号读法
| 信号 | 方向 | 含义 |
|---|---|---|
| 窗口字段为 0 | 接收端发出 | 缓冲写满,暂停发送 |
| 零载荷的小包周期出现 | 发送端发出 | 窗口探测,等待对端放开 |
| 窗口字段由 0 变为正值 | 接收端发出 | 应用已读取数据,可以继续 |
| 零窗口长时间不恢复 | 接收端侧 | 应用阻塞,抓包只能定位到这一侧 |
零窗口之后发送端发窗口探测是协议规定的正常行为,不要误判为重传风暴。
零窗口是分方向的:同一连接可能一个方向卡住、另一个方向仍然通畅,分析时必须区分。
进阶要点
- 零窗口与丢包是两回事:前者没有丢包,只是接收端主动要求暂停
- 统计零窗口持续时长比统计出现次数更有意义,时长直接对应业务卡顿时间
- 同步对照接收端应用日志的读取记录,才能把窗口归零与具体处理阶段对应起来
- 同一连接的相反方向可能仍在正常传输,分析时必须按方向分别统计
- 长连接反复归零时除优化应用外,还要检查中间设备的会话老化时间
只看一端的抓包只能证明「本侧所见」,判断窗口归零的成因最好两侧同时取证。