TCP 连接状态详解

TCP 连接状态由 RFC 793 定义,共 11 种标准状态。以下按连接生命周期详细解释:


1. 连接建立阶段

LISTEN (监听)

  • 状态值0A(十六进制)/ 10(十进制)

  • 含义:服务器端等待客户端的连接请求

  • 触发条件 :调用 listen() 系统调用后

  • 查看方法

    bash 复制代码
    ss -lnt      # 查看所有监听端口
    netstat -lnt
  • 典型场景

    bash 复制代码
    # Web服务器监听
    Proto Recv-Q Send-Q Local Address:Port  Peer Address:Port  
    tcp   0      0      *:80                *:*              LISTEN

SYN-SENT (同步已发送)

  • 状态值02 / 2

  • 含义:客户端发送 SYN 后等待服务器回复

  • 触发条件 :调用 connect() 后,发送 SYN 包

  • 持续时间:通常很短(RTT + 处理时间)

  • 问题诊断

    bash 复制代码
    # 大量SYN-SENT可能表示:
    # 1. 服务器未响应
    # 2. 防火墙阻止
    ss -ant | grep -c SYN-SENT

SYN-RECEIVED (同步已接收)

  • 状态值03 / 3

  • 别名:SYN-RCVD

  • 含义:服务器收到 SYN,发送 SYN+ACK 后等待客户端 ACK

  • 触发条件:服务器收到 SYN,发送 SYN+ACK 后

  • 半连接队列 :处于此状态的连接在半连接队列(SYN Queue)

  • 安全注意SYN Flood 攻击的目标状态

  • 调优参数

    bash 复制代码
    sysctl net.ipv4.tcp_max_syn_backlog    # 半连接队列大小
    sysctl net.ipv4.tcp_syncookies         # 防御SYN Flood

2. 连接已建立阶段

ESTABLISHED (已建立连接)

  • 状态值01 / 1

  • 含义:连接已建立,可以正常传输数据

  • 触发条件:完成三次握手后

  • 全连接队列 :从 SYN-RCVD 移入全连接队列(Accept Queue)

  • 查看详细

    bash 复制代码
    # 查看所有已建立连接
    ss -nt
    # 按进程查看
    ss -ntp
  • 数据传输

    lua 复制代码
    客户端                                   服务器
      |           ESTABLISHED              |
      | <-------------------------------> |
      |         数据自由流动               |

3. 连接关闭阶段(正常关闭)

FIN-WAIT-1 (结束等待1)

  • 状态值04 / 4

  • 含义:主动关闭方发送 FIN 后,等待对方 ACK

  • 触发条件 :调用 close()shutdown(SHUT_WR)

  • 可能转换

    scss 复制代码
    FIN-WAIT-1 → FIN-WAIT-2      # 收到ACK
    FIN-WAIT-1 → CLOSING         # 同时收到FIN(同时关闭)
    FIN-WAIT-1 → TIME-WAIT       # 收到FIN+ACK

FIN-WAIT-2 (结束等待2)

  • 状态值05 / 5

  • 含义:收到对方对 FIN 的 ACK,等待对方发送 FIN

  • 持续时间:可保持较长时间(对方还未调用 close)

  • 查看

    bash 复制代码
    # 查看处于此状态的连接
    ss -ant | grep FIN-WAIT-2
  • 问题 :过多连接可能导致资源耗尽

    bash 复制代码
    sysctl net.ipv4.tcp_fin_timeout  # 默认60秒

CLOSE-WAIT (关闭等待)

  • 状态值08 / 8

  • 含义:被动关闭方收到 FIN 后,等待应用层关闭

  • 触发条件:收到对方的 FIN,发送 ACK 后

  • 关键问题应用层未及时关闭连接 会导致大量 CLOSE-WAIT

    bash 复制代码
    # 排查方法
    ss -ant | grep CLOSE-WAIT
    # 找到对应进程
    ss -antp | grep CLOSE-WAIT
    
    # 常见原因:未调用 close(),连接泄漏

CLOSING (正在关闭)

  • 状态值0B / 11

  • 含义 :双方同时尝试关闭连接(罕见)

  • 触发条件

    lua 复制代码
    双方几乎同时发送FIN
    客户端: FIN-WAIT-1 --发送FIN--> 服务器
    服务器: FIN-WAIT-1 --发送FIN--> 客户端
    双方收到对方FIN后进入CLOSING
  • 查看

    bash 复制代码
    # 通常很少见
    ss -ant | grep -c CLOSING

LAST-ACK (最后确认)

  • 状态值09 / 9
  • 含义:被动关闭方发送自己的 FIN 后,等待最后 ACK
  • 触发条件:CLOSE-WAIT 状态的应用调用 close() 后
  • 转换:收到 ACK 后进入 CLOSED

TIME-WAIT (时间等待)

  • 状态值06 / 6

  • 含义:主动关闭方收到对方的 FIN 并发送 ACK 后

  • 持续时间2MSL (Maximum Segment Lifetime)

    • 默认:60秒(Linux)
    • 查看:sysctl net.ipv4.tcp_fin_timeout
  • 目的

    1. 确保对方收到最后的 ACK
    2. 让旧连接的数据包在网络中消失
  • 查看和管理

    bash 复制代码
    # 统计数量
    ss -ant | grep -c TIME-WAIT
    
    # 查看详细信息
    ss -ant state time-wait
    
    # 调优参数
    sysctl net.ipv4.tcp_tw_reuse      # 重用TIME-WAIT连接
    sysctl net.ipv4.tcp_tw_recycle    # 快速回收(谨慎使用)
    sysctl net.ipv4.tcp_max_tw_buckets # 限制数量

4. 特殊/终止状态

CLOSED (关闭)

  • 状态值07 / 7
  • 含义:连接完全关闭,无资源占用
  • 注意:统计中通常看不到,因为已释放资源

状态转换图详解

sql 复制代码
                              +---------+
                              |  CLOSED |
                              +---------+
                  被动打开        |     主动打开
                   LISTEN        |     SYN-SENT
                     |           |        |
                     v           |        |
                +---------+      |        |
                |  LISTEN |      |        |
                +---------+      |        |
          收到SYN   |             |        |
             发送SYN+ACK |             |        |
                     |           |        |
                     v           |        |
               +-----------+     |        |
               |SYN-RECEIVED|<---|--------+
               +-----------+     |  收到ACK
          收到ACK   |             |        |
              |           |        |
              v           |        |
          +---------+     |        |
          |ESTABLISHED|<--+--------+
          +---------+             连接建立完成
              |                       |
              |     应用数据传输       |
              |                       |
              |    主动关闭           被动关闭
              |   发送FIN             收到FIN
              |                      发送ACK
              v                       |
          +---------+               +-----------+
          |FIN-WAIT-1|              | CLOSE-WAIT|
          +---------+               +-----------+
              |                       |
   收到ACK     |                       |应用调用close
              v                       |发送FIN
          +---------+               +---------+
          |FIN-WAIT-2|              |LAST-ACK |
          +---------+               +---------+
              |                       |
   收到FIN     |                       |收到ACK
   发送ACK     |                       |
              v                       v
          +---------+               +---------+
          |TIME-WAIT|               |  CLOSED |
          +---------+               +---------+
              |  等待2MSL
              v
          +---------+
          |  CLOSED |
          +---------+

完整查看脚本

bash 复制代码
#!/bin/bash
# tcp_state_detailed.sh
# 查看详细的TCP状态统计

echo "================================================"
echo "            TCP 连接状态详细统计"
echo "================================================"
echo ""

# 使用 ss 查看(推荐)
echo "【方法1: ss 命令】"
echo "状态             数量   描述"
echo "-----------------------"
ss -ant | awk 'NR>1 {print $2}' | sort | uniq -c | while read count state; do
    case $state in
        LISTEN)     desc="监听端口,等待连接" ;;
        SYN-SENT)   desc="客户端已发送SYN" ;;
        SYN-RECV)   desc="服务器收到SYN,已回复SYN+ACK" ;;
        ESTAB)      desc="连接已建立,数据传输中" ;;
        FIN-WAIT-1) desc="主动关闭方发送FIN,等待ACK" ;;
        FIN-WAIT-2) desc="收到FIN的ACK,等待对方FIN" ;;
        TIME-WAIT)  desc="等待2MSL,确保连接完全关闭" ;;
        CLOSED)     desc="连接完全关闭" ;;
        CLOSE-WAIT) desc="被动关闭方收到FIN,等待应用关闭" ;;
        LAST-ACK)   desc="被动关闭方发送FIN,等待最后ACK" ;;
        CLOSING)    desc="双方同时尝试关闭" ;;
        UNKNOWN)    desc="未知状态" ;;
        *)          desc="" ;;
    esac
    printf "%-12s %6d    %s\n" "$state" "$count" "$desc"
done

echo ""
echo "【方法2: /proc/net/tcp 原始数据】"
echo "状态(十六进制) 数量"
echo "-------------------"
awk '{print $4}' /proc/net/tcp | awk -F: '{print $1}' | sort | uniq -c | sort -rn | while read count hex_state; do
    case $hex_state in
        0A) state="LISTEN" ;;
        01) state="ESTABLISHED" ;;
        02) state="SYN_SENT" ;;
        03) state="SYN_RECV" ;;
        04) state="FIN_WAIT1" ;;
        05) state="FIN_WAIT2" ;;
        06) state="TIME_WAIT" ;;
        07) state="CLOSE" ;;
        08) state="CLOSE_WAIT" ;;
        09) state="LAST_ACK" ;;
        0B) state="CLOSING" ;;
        *)  state="UNKNOWN($hex_state)" ;;
    esac
    printf "%-10s %6s    %6d\n" "$hex_state" "$state" "$count"
done

echo ""
echo "【关键指标监控】"
total=$(ss -ant | grep -c -v State)
echo "总TCP连接数: $total"
echo ""

# 监控建议
echo "【健康检查建议】"
close_wait=$(ss -ant state close-wait | grep -c -v State)
if [ $close_wait -gt 100 ]; then
    echo "⚠️  警告: CLOSE-WAIT 过多($close_wait),可能存在连接泄漏"
    echo "   排查方法:"
    echo "   1. ss -antp state close-wait"
    echo "   2. 检查对应应用的连接关闭逻辑"
fi

time_wait=$(ss -ant state time-wait | grep -c -v State)
if [ $time_wait -gt 10000 ]; then
    echo "⚠️  警告: TIME-WAIT 过多($time_wait),可能影响新连接"
    echo "   优化建议:"
    echo "   1. sysctl net.ipv4.tcp_tw_reuse=1"
    echo "   2. sysctl net.ipv4.tcp_max_tw_buckets=2000000"
fi

状态诊断与调优

常见问题及解决

问题1:大量 TIME-WAIT

bash 复制代码
# 原因:短连接过多
# 解决:
sysctl -w net.ipv4.tcp_tw_reuse=1      # 重用
sysctl -w net.ipv4.tcp_tw_recycle=1    # 回收(NAT环境慎用)
sysctl -w net.ipv4.tcp_max_tw_buckets=2000000

问题2:大量 CLOSE-WAIT

bash 复制代码
# 原因:应用未正确关闭连接
# 排查:
lsof -nP -iTCP -sTCP:CLOSE_WAIT
# 或
ss -antp state close-wait
# 检查对应进程的代码

问题3:大量 SYN-RECV

bash 复制代码
# 原因:可能遭受SYN Flood攻击
# 防御:
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
sysctl -w net.ipv4.tcp_synack_retries=2

状态监控工具

实时监控脚本

bash 复制代码
#!/bin/bash
# 实时监控TCP状态变化
watch -n 1 '
echo "TCP状态实时监控 - $(date)"
echo "----------------------------------------"
ss -ant | awk '\''NR>1 {count[$2]++} END {
    states["LISTEN"]="监听";
    states["SYN-SENT"]="发SYN";
    states["SYN-RECV"]="收SYN";
    states["ESTAB"]="已连接";
    states["FIN-WAIT-1"]="等FIN-ACK";
    states["FIN-WAIT-2"]="等对方FIN";
    states["TIME-WAIT"]="等2MSL";
    states["CLOSE-WAIT"]="等应用关";
    states["LAST-ACK"]="等最后ACK";
    states["CLOSING"]="同时关闭";
    for(s in count) {
        printf "%-12s %6d  %s\n", s, count[s], states[s]
    }
}'\'' | sort
'
相关推荐
mangge081 天前
ESP8266 温湿度监测系统教程(SHT30+MAX7219+LeanCloud+HTTP 服务)
网络·网络协议·http
阿巴~阿巴~1 天前
“可达”方能“可靠”:深入解析网络层在TCP通信中的基石作用
运维·服务器·网络·网络协议·tcp/ip·ip·tcp
安生生申1 天前
HTTP与HTTPS的区别
网络协议·http·https
北京耐用通信1 天前
耐达讯自动化CAN转PROFIBUS网关让软启动器如何让包装线告别“信号迷宫”
人工智能·物联网·网络协议·自动化·信息与通信
一只小鱼儿吖1 天前
携趣HTTP代理浏览器设置器(PC版)使用指南
网络·网络协议·http
乾元1 天前
企业无线的 AI 频谱与功率自动优化——从人工勘测到“可学习的无线网络”(含真实室内工程案例)
服务器·网络·人工智能·网络协议·安全·信息与通信
meichao91 天前
springboot3.5.8集成websocket问题
网络·spring boot·websocket·网络协议
ICT系统集成阿祥1 天前
哪些功能是对交换机的性能消耗比较大?
网络·网络协议
-芒果酱-1 天前
常见的PON网络协议
网络·网络协议