飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • IP协议

    • 认识 IP 协议与网络层定位
    • IPv4 编址体系与分类地址
    • CIDR 与子网划分实战
    • IPv6 编址体系
    • ARP 协议详解
    • NDP 协议详解
    • IGMP 与 MLD 组播侦听发现
    • VRRP 与网关冗余
    • IPv4 数据报首部解析
    • IPv6 数据报与扩展首部
    • IPsec 安全扩展
    • 分片、MTU 与路径发现
    • ICMP 与 Traceroute 原理
    • 路由基础与转发流水线
    • 动态路由协议
    • NAT 网络地址转换
    • DHCP 与自动配置
    • Wireshark 与命令行工具
    • IPv6 过渡技术
    • IP 协议栈排障与攻击防御
  • TCP协议

    • 认识 TCP 协议与传输层定位
    • TCP 报文段首部解析
    • 三次握手与连接建立
    • 四次挥手与连接释放
    • TCP 有限状态机
    • 序列号与确认机制
    • 超时重传与 RTO 计算
    • 滑动窗口与流量控制
    • 拥塞控制基础
    • 现代拥塞控制算法
    • TCP 选项与扩展
    • TCP 性能调优与内核参数
    • Nagle 算法与糊涂窗口综合征
    • TCP 定时器与 Keep-Alive 机制
    • TCP 安全与攻击防御
    • TCP 与上层/下层交互
    • TCP 综合实践与排障

TCP 有限状态机

什么是有限状态机

TCP 用**有限状态机(Finite State Machine, FSM)**精确描述连接从建立到释放的全生命周期。共定义 11 种状态,每个状态由特定事件(收到报文、应用层调用、超时)触发转换。

11 种状态详解

状态说明典型场景
CLOSED无连接初始状态或连接完全关闭
LISTEN监听服务端等待客户端连接
SYN_SENTSYN 已发送客户端发送 SYN 后等待回复
SYN_RCVDSYN 已收到服务端收到 SYN 并回复 SYN-ACK
ESTABLISHED连接建立数据传输阶段
FIN_WAIT_1FIN 已发送主动关闭方发送 FIN 后等待 ACK
FIN_WAIT_2FIN 已确认收到 ACK,等待对方 FIN
CLOSE_WAIT收到对方 FIN被动关闭方等待应用层关闭
CLOSING同时关闭双方同时发送 FIN
LAST_ACK最后确认被动关闭方发送 FIN 后等待 ACK
TIME_WAIT等待 2MSL确保可靠终止 + 防止旧报文干扰

客户端与服务端状态转换对比

客户端:主动发起连接,主动关闭连接,经历 TIME_WAIT 服务端:被动接受连接,被动关闭连接(通常),不经历 TIME_WAIT

异常状态转换

RST 重置连接

收到 RST 报文时,连接立即进入 CLOSED,不经过四次挥手:

触发 RST 的场景:

  • 端口未监听(Connection Refused)
  • 连接异常(如中间防火墙切断)
  • 应用层强制关闭(SO_LINGER 选项)
  • 收到不属于任何连接的报文

同时打开与同时关闭

同时打开(双方同时发送 SYN):

CLOSED → SYN_SENT → SYN_RCVD → ESTABLISHED

同时关闭(双方同时发送 FIN):

ESTABLISHED → FIN_WAIT_1 → CLOSING → TIME_WAIT → CLOSED

查看连接状态

# Linux: 查看各状态连接数量
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

# 典型输出
  500 ESTAB
  200 TIME-WAIT
   50 CLOSE-WAIT
   10 SYN-RECV
    5 LISTEN

CLOSE_WAIT 过多:说明服务端应用层没有及时关闭连接(如忘记调用 close()),需检查代码。

SYN_RECV 过多:可能遭受 SYN Flood 攻击。

TIME_WAIT 过多:主动关闭方频繁断连,考虑连接复用。

本篇小结

  • TCP 定义 11 种状态,构成有限状态机
  • 正常流程:CLOSED → LISTEN/SYN_SENT → SYN_RCVD → ESTABLISHED → FIN_WAIT → TIME_WAIT → CLOSED
  • RST 立即终止连接,不经过四次挥手
  • 同时打开:双方都走 SYN_SENT → SYN_RCVD → ESTABLISHED
  • 同时关闭:双方都走 FIN_WAIT_1 → CLOSING → TIME_WAIT
  • 通过 ss -tan 监控各状态数量,定位问题

动手实践

  1. 查看本机各 TCP 状态数量:

    ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
    
  2. 找到处于 CLOSE_WAIT 的连接,查看对应的进程:

    ss -tp | grep CLOSE-WAIT
    
  3. 用 telnet 连接一个不存在的端口,观察 RST 报文(Wireshark 过滤 tcp.flags.rst==1)

  4. 思考:为什么服务端通常不进入 TIME_WAIT?如果服务端主动关闭连接,会有什么后果?

上一页
四次挥手与连接释放
下一页
序列号与确认机制