Skip to content

TCP 状态速查表

TCP 连接的状态是针对单个端点而言的。在一次完整的连接中,客户端和服务端会各自维护一份独立的 TCP 状态记录,因此在同一时刻,两端看到的状态很可能并不一致。在排障时,建议同时记录当前端点的角色(客户端/服务端)、网络四元组、状态持续时间、相关联的进程以及网络抓包数据。

状态总表

状态当前含义常见进入事件常见退出事件排障提示
CLOSED当前没有任何活动的 TCP 连接状态初始状态、连接释放完成、或失败后被清理主动调用 connect 或被动开启监听系统命令(如 netstat/ss)通常不会显示没有控制块的 CLOSED 状态;遇到 API 报错时,可通过抓包来补充排查失败原因
LISTEN本地端点正在等待并接受发往该地址和端口的新连接bind 之后调用 listen应用主动关闭监听端点后释放资源;收到 SYN 报文时,会创建新连接并使其进入 SYN-RECEIVED 状态,原监听端点继续保持 LISTEN排障时优先核对绑定地址(如 0.0.0.0 等)、地址族、端口号、关联进程、队列溢出情况以及防火墙规则
SYN-SENT主动方(通常是客户端)已发送 SYN 报文,正在等待对端的确认响应阻塞或非阻塞调用 connect 发起连接收到 SYN+ACK 后发送最终 ACK,随后进入 ESTABLISHED;超时或发生错误则被清理如果卡在该状态的时间较长,需排查 SYN 重传情况、路由配置、ACL 策略、目标端是否在监听以及返回路径是否通畅
SYN-RECEIVED已收到对端的 SYN 报文并回复了 SYN+ACK,正在等待对方的最终确认(ACK)处于被动打开状态(LISTEN)收到 SYN;“同时打开”时也可能进入此状态收到有效的 ACK 后进入 ESTABLISHED;超时未收到确认则被内核回收若出现大量积压,需重点检查握手完成率、半连接队列容量、是否触发 SYN Flood 防护机制以及网络返回路径是否正常
ESTABLISHED双方已成功建立连接,可以进行双向数据传输三次握手完成本端主动关闭进入 FIN-WAIT-1;收到对端的 FIN 进入 CLOSE-WAIT;收到有效的 RST 会立即终止连接长时间处于空闲状态可能是正常的连接池设计;需结合应用层心跳、代理超时配置与业务日志来综合判断连接是否依然健康
FIN-WAIT-1本端已发送 FIN 报文,正在等待对端的确认(ACK)或对端发来的 FIN本端主动调用 closeshutdown 结束发送通道收到针对本端 FIN 的 ACK 后进入 FIN-WAIT-2;若同时收到对端的 FIN,则可能进入 CLOSING 或 TIME-WAIT若该状态持续堆积,需核对对端是否收到了 FIN、返回的 ACK 是否因网络原因丢失,以及本地是否有持续的 FIN 重传
FIN-WAIT-2本端的 FIN 已经被对端确认,正在等待对端发送 FIN 以结束其发送通道在 FIN-WAIT-1 状态下收到了 ACK收到对端的 FIN 后,回复 ACK 并进入 TIME-WAIT长期卡在此状态通常意味着对端仍在发送数据,或者对端应用的关闭流程卡死了;注意内核通常会针对此类孤儿连接设置超时回收策略
CLOSE-WAIT本端已收到对端的 FIN,但本地应用尚未关闭其发送通道在 ESTABLISHED 状态下收到 FIN本地应用调用 close 完成关闭并发送 FIN 后,进入 LAST-ACK如果出现大量且长期的 CLOSE-WAIT,优先检查本地应用逻辑:是否正确处理了 EOF、线程是否死锁卡住、异常处理分支是否漏调了 Socket 的关闭方法
CLOSING双方几乎同时发送了 FIN,且本端的 FIN 尚未收到确认在 FIN-WAIT-1 状态下收到了对端的 FIN,并已对其回复了 ACK收到针对本端 FIN 的 ACK 后,进入 TIME-WAIT这种状态在实际中出现频率较低;通过网络抓包可以清晰确认双方 FIN 报文的交叉发送顺序
LAST-ACK本端(作为被动关闭方)已发送 FIN,正在等待最后的 ACK 确认在 CLOSE-WAIT 状态下,本地应用主动关闭了发送通道收到最终的 ACK 后进入 CLOSED 状态;如果超时会重传 FIN 并最终由内核强制清理若持续卡在此状态,需检查最后的 ACK 返回路径是否受阻、对端的当前状态,以及是否受到防火墙等中间设备的影响
TIME-WAIT连接已关闭,但本端(主动关闭方)仍保留短期记录以处理网络中可能延迟到达的报文主动关闭方确认了对端的 FIN;或者双方同时完成关闭计时器(通常为 2MSL)到期后,彻底进入 CLOSED 状态需重点观察连接的创建速率、可用临时端口范围、谁是主动关闭方以及对系统资源的实际影响;TIME-WAIT 数量多往往只是现象,不必盲目优化

主动建立路径

客户端(发起方)的常见状态流转路径:

text
CLOSED
  │ connect,发送 SYN

SYN-SENT
  │ 收到 SYN+ACK,发送 ACK

ESTABLISHED

服务端(接收方)的监听端点始终保持在 LISTEN 状态。每当有新连接到来时,内核会为其维护独立的状态流转:

text
LISTEN
  │ 收到 SYN,为新连接发送 SYN+ACK

SYN-RECEIVED
  │ 收到最终 ACK

ESTABLISHED
  │ 进入已完成连接队列,等待应用完成 accept

应用持有已连接 Socket

应用层调用 accept 会取得已经成功建立的连接。TCP 握手完成的时刻和应用层调用 accept 的时刻是解耦的,全连接队列在底层将这两个不同步的节奏连接了起来。

本端主动关闭路径

当本端率先结束发送通道(即主动触发断开连接)时,常见的状态流转如下:

text
ESTABLISHED
  │ 本端发送 FIN

FIN-WAIT-1
  │ 对端确认本端 FIN

FIN-WAIT-2
  │ 对端稍后发送 FIN,本端回复 ACK

TIME-WAIT
  │ 计时器到期

CLOSED

值得注意的是,在进入 FIN-WAIT-2 阶段后,对端依然可以继续发送数据(半关闭状态)。此时本端的接收通道仍保持正常工作,直到最终收到对端发来的 FIN 报文,并将接收缓冲区中剩余的字节悉数交给应用层读取。

本端被动关闭路径

当本端率先收到对端发来的 FIN 报文(即被动断开连接)时,常见的状态流转如下:

text
ESTABLISHED
  │ 收到 FIN,回复 ACK

CLOSE-WAIT
  │ 应用完成工作并关闭连接,发送 FIN

LAST-ACK
  │ 收到最终 ACK

CLOSED

CLOSE-WAIT 状态的持续时间,很大程度上取决于本地应用的实现逻辑。当应用在读取操作中收到 EOF 后,它可以继续向对端发送完剩下的响应数据,随后再调用 shutdownclose 来彻底完成本方向的关闭流程。

同时关闭

如果双方在极其相近的时间点相互发送了 FIN 报文,可能会出现以下流转:

text
ESTABLISHED
  │ 本端发送 FIN

FIN-WAIT-1
  │ 收到对端 FIN,先回复 ACK

CLOSING
  │ 收到本端 FIN 的 ACK

TIME-WAIT

在实际的网络抓包中,ACK 和 FIN 标志位经常会合并在同一个报文中出现(FIN+ACK),偶尔的重传也会使得实际报文数量多于理论值。因此,在分析状态迁移时,关注底层事件的核心语义(谁发送了数据、谁确认了状态),比死记硬背固定的报文数量要稳定得多。

半关闭与 EOF

调用 shutdown(SHUT_WR) 会关闭本端的发送通道,但接收通道依然保持开启。这意味着,对端在读完缓冲区中已有的字节后会收到一个 EOF,但本端依然可以继续读取对端随后发来的响应数据。

本端动作或事件本端的发送通道本端的接收通道
调用 shutdown(SHUT_WR)进入关闭流程并向外发送 FIN保持正常,依然可读
收到对端的 FIN仍可根据本地应用需要继续发送数据读取完底层缓存数据后,向应用层报告 EOF
调用完整的 close由底层协议栈负责完成关闭,或者按配置直接中止连接应用层立即失去对该 Socket 句柄的控制权

RST 对状态的影响

一个有效的 RST 报文通常会立即终止当前的连接状态,并导致处于阻塞状态或后续调用的 Socket API 立即抛出错误。导致产生 RST 的常见场景包括:

  • 访问的目标端口上没有任何进程在监听;
  • 主机收到了属于某个已失效旧连接的报文,且当前系统中找不到匹配的连接状态;
  • 应用层采取了中止式关闭(Abortive Close);
  • 连接的某一方意外重启,丢失了原有的 TCP 状态机信息;
  • 链路上的防火墙或中间网络设备主动切断并拒绝了该连接。

为了防止网络攻击,RST 报文是否被接受,还会受到当前连接状态以及各种 TCP 安全增强规范(如对序列号的严格校验)的约束。在分析此类问题时,务必记录下 RST 的实际发送方、Ack/Seq 字段、发生该事件前的前置操作,以及应用层具体的关闭方式。

常见状态组合

现象观察首要排查方向进一步佐证的线索
客户端处于 SYN-SENT,但服务端毫无记录目标地址和端口是否正确、路由配置、防火墙策略,以及抓包点位置是否合理两端同时抓包的比对结果、系统的路由表、服务端的监听状态
服务端 SYN-RECEIVED 状态大量积压客户端的最终 ACK 是否未能返回、半连接队列是否溢出、是否遭受 SYN Flood 攻击抓包统计 SYN/SYN+ACK/ACK 的比例、系统队列监控指标
服务端 CLOSE-WAIT 状态持续增长应用层是否正确处理了 EOF、连接资源的释放逻辑是否有漏洞应用程序的线程栈分析(排查阻塞)、连接对象的创建与关闭日志
客户端 FIN-WAIT-2 状态长期存在了解对端应用的代码逻辑,排查其何时才会结束发送通道对端的 TCP 状态表、对端应用日志、FIN 报文相关的抓包
系统存在海量的 TIME-WAIT业务短连接的并发速率、哪一方在主动关闭连接、临时端口资源是否枯竭端口四元组的分布统计、系统可用临时端口范围、连接池的监控指标
LAST-ACK 状态持续不消失最终 ACK 的网络返回路径是否顺畅、对端目前处于什么状态两端同时抓包、防火墙的会话超时设置、是否有 FIN 报文重传

排障记录模板

在进行排障并查询连接状态时,建议记录以下要素:

text
时间:
主机与网络命名空间:
进程/PID:
本地地址与端口:
远端地址与端口:
TCP 状态:
持续时间或首次观察时间:
同类连接数量:
对应日志事件:
对应抓包帧号:

单次记录的状态快照仅仅代表某一特定时刻的切片。只有通过连续多次采样,才能真实揭示该连接是处于正常的流转中、稳定的空闲状态,还是由于某种异常而长期停滞在同一个阶段。

上一页:TCP 字段速查表 · 返回附录目录 · 下一页:Wireshark 过滤器速查

Licensed under CC BY-NC-SA 4.0.