双方同时关闭会发生什么
正常关闭是一条四次挥手:一端先发 FIN,另一端确认后再发自己的 FIN。如果双方几乎同时决定结束,就会出现同时关闭:各自发出 FIN,各自确认对方的 FIN,随后两条方向分别走完关闭流程。抓包的表现是两侧的 FIN 在时间上很接近,互相交叉,而不是先关完一头再关另一头。这是状态机里定义好的正常分支,不是异常断连。
基本信息
| 抓包表现 | 两侧 FIN 时间接近,各自发出并被对方确认 |
|---|---|
| 典型顺序 | A 发 FIN 的同时 B 也发 FIN,双方各自回 ACK 后完成关闭 |
| 状态变化 | 两端分别经历发出 FIN、收到确认、等待对端 FIN、最终关闭 |
| 高发场景 | 对称协议、双方同时判断任务结束的场景 |
| 少见原因 | 常见的请求响应模型通常是一端先关,出现概率较低 |
| 排查前提 | 多点抓包时需对齐时钟,中间设备可能只看到单向 FIN |
典型使用场景
- 误报澄清:把交叉 FIN 从「异常断开」里排除,避免误判应用崩溃
- 协议讲解:用实际抓包展示状态机的非典型分支
- 中间设备排查:确认防火墙或负载均衡是否正确转发了双向的 FIN
- 日志对齐:把两侧日志里的关闭时间与抓包交叉验证
- 连接回收分析:确认连接是自然关闭还是被复位,为资源统计提供依据
看两侧 FIN 的时间关系
看两侧 FIN 的时间关系
# 列出所有 FIN, 按时间排序, 观察是否成对出现
tshark -r a.pcap -Y 'tcp.flags.fin == 1' -T fields -e frame.number -e frame.time_relative -e ip.src -e ip.dst -e tcp.stream | head -30
# 只看某条连接的关闭过程
tshark -r a.pcap -Y 'tcp.stream == 7 && (tcp.flags.fin == 1 || tcp.flags.reset == 1)' -T fields -e frame.number -e frame.time_relative -e ip.src -e tcp.flags.str
# 两端分别抓包时, 先确认两侧时钟已对齐再比对
tshark -r client.pcap -Y 'tcp.flags.fin == 1' -T fields -e frame.number -e frame.time -e ip.src关闭流程对照
| 情形 | 抓包特征 | 判读 |
|---|---|---|
| 正常四次挥手 | 一端 FIN, 另一端先 ACK 后 FIN | 最常见, 无异常 |
| 同时关闭 | 两端 FIN 交叉出现 | 正常分支, 不是断连 |
| 一端复位 | 出现 RST 而非 FIN 交互 | 需要结合应用行为判断 |
| 中间设备只转发单向 FIN | 一端看到 FIN, 另一端看不到 | 检查设备对双向 FIN 的转发 |
| 一端先超时回收 | 另一端的写操作触发复位 | 超时参数两端不一致 |
出现同时关闭不必修复:它只是状态机的一条合法路径。真正需要关注的是关闭之后的复位,以及两端对关闭时机的理解是否一致。
跨设备抓包比对关闭时序前先对齐时钟,否则相隔几毫秒的两条 FIN 会被看成相隔几分钟,得出完全错误的先后关系。