TCP 半关闭状态
一方发出 FIN 之后连接进入半关闭状态:本方向不再发送数据,但反方向仍然可以继续发送,直到对方也发出 FIN。多数请求响应类协议会直接双向关闭,而需要服务端持续推送的长连接协议要专门处理半关闭,否则会出现提前清理资源的问题。
基本信息
| 适用平台 | TCP 状态机行为,各系统实现一致 |
|---|---|
| 观察方式 | FIN 之后同方向不再有数据,反方向流量继续 |
| 相关状态 | 主动关闭方进入等待状态,被动方进入关闭等待 |
| 协议依据 | RFC 9293(连接状态机) |
典型使用场景
- 理解 FIN 的含义:它表示本方向没有更多数据,不等于连接彻底断开
- 排查推送中断:服务端继续写数据时收到重置,多为应用提前收摊
- 分析协议设计:对比不同协议对半关闭的处理差异
- 排查资源泄漏:只关一半的连接会长期占用描述符
- 验证关闭顺序:确认两侧 FIN 都已出现才算完整关闭
判读要点
判读要点
# 客户端发 FIN 后,服务端仍可继续推送数据
# 服务端应用需要感知「对端不再发送」
# 半关闭期间向已关闭方向发数据会收到重置
# 完整关闭需要两侧的 FIN 都出现阶段判读
| 阶段 | 发送方向 | 说明 |
|---|---|---|
| 一方发出 FIN | 该方向停止 | 反方向仍可继续发送 |
| 双方都发出 FIN | 双向停止 | 开始进入收尾与超时等待 |
| 向已关闭方向发数据 | 触发重置 | 应用逻辑需要处理这种异常 |
| 连接长期只关一半 | 占用资源 | 可能造成描述符泄漏 |
抓包里看到一个 FIN 并不代表连接已经结束,要等两侧的 FIN 都出现才算完成关闭流程。判断业务是否真的断开时,必须看完整的关闭序列。
服务端在推送过程中突然收到重置,常见原因是客户端已经彻底关闭连接,而服务端仍在继续写。排查推送类业务的中断问题时要留意这个顺序。
只关闭一半的连接会长时间占用描述符资源。如果服务端出现描述符缓慢增长,值得检查应用是否正确处理了对方的半关闭。