Linux内核通过/proc/net/tcp和/proc/net/udp第4列十六进制状态码(如01=ESTABLISHED、0A=LISTEN、06=TIME_WAIT)提供TCP/UDP套接字当前快照,结合ss -o可查看计时器细节,辅以/proc/$pid/fd与inode交叉匹配进程级连接,或用ftrace/perf追踪tcp_set_state实现变迁分析。

直接看 /proc/net/tcp 和 /proc/net/udp 的状态列
Linux 内核把每个 TCP 套接字的当前状态以十六进制编码写在 /proc/net/tcp(IPv4)或 /proc/net/tcp6(IPv6)的第 4 列,UDP 则在 /proc/net/udp 中同理。这不是“变迁记录”,而是**当前快照**——但它是内核状态机最真实的反映来源。
常见状态码:01 是 ESTABLISHED,0A 是 LISTEN,06 是 TIME_WAIT,02 是 SYN_SENT,08 是 CLOSE_WAIT。这些值来自内核头文件 include/net/tcp_states.h,不能靠猜,得查文档或用脚本映射。
- 用
awk '{print $4}' /proc/net/tcp | sort | uniq -c快速统计各状态数量 - 过滤监听态:
awk '$4 == "0A" {print}' /proc/net/tcp - 注意:该文件每行对应一个套接字,但不包含历史变迁;它只告诉你“此刻是什么状态”
用 ss -o 查看带计时器的套接字状态细节
ss -o 会显示每个连接的内核定时器信息(如 retransmit、keepalive、rto 等),这些字段间接反映状态正在“动”——比如一个处于 CLOSE_WAIT 的连接如果 timer:(keepalive,15sec,0),说明它正等待应用层 close();而 timer:(on,15sec,0) 在 TIME_WAIT 中,表示还有 15 秒才真正释放。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
-
ss -tano state close-wait:只看 CLOSE_WAIT 连接及其计时器 -
ss -tino dst 192.168.1.100:加-i显示内部 socket 信息(含重传次数、RTT 估值等) - ⚠️ 注意:
ss -o输出中的 timer 字段不是所有状态都存在,比如 LISTEN 没有 keepalive 计时器,但可能有 syn_retries 相关字段
通过 /proc//fd/ 配合 lsof 看用户态视角的套接字生命周期
内核状态是底层事实,但用户态进程对套接字的调用(socket() → bind() → listen() → accept() → close())决定了状态如何变迁。你可以从进程 fd 入口反推:
-
ls -l /proc/<pid>/fd/ | grep socket</pid>:看到类似socket:[123456]的条目,其中数字是 inode 号 -
grep -r 123456 /proc/net/{tcp,udp}:定位该 inode 对应的内核套接字行,确认当前状态 -
lsof -nP -p <pid> | grep -E '(TCP|UDP)'</pid>:比ss -p更易读地关联进程与 socket 状态,但依赖 /proc//fd 下的符号链接是否有效 - ⚠️ 容易踩坑:一旦进程 close() 了 fd,inode 号就失效,
/proc/net/中对应行也会消失——所以“变迁”必须靠多次采样对比,无法回溯
用 perf trace 或 ftrace 抓取 socket 系统调用路径
真要看“变迁过程”,唯一办法是跟踪内核中 socket 状态变更的关键点,比如 tcp_set_state()。这需要启用 ftrace 或用 perf trace 监控系统调用和内核函数:
-
sudo perf trace -e 'syscalls:sys_enter_bind,syscalls:sys_enter_listen,syscalls:sys_enter_accept,syscalls:sys_enter_close':抓用户态触发点 -
echo 'tcp_set_state' > /sys/kernel/debug/tracing/set_ftrace_filter; echo 1 > /sys/kernel/debug/tracing/events/tcp/tcp_set_state/enable:开启内核态状态变更 trace(需 CONFIG_FTRACE=y) - 输出示例:
tcp_set_state: sk=ffff9a... oldstate=TCP_CLOSE newstate=TCP_LISTEN - ⚠️ 复杂点在于:ftrace 输出是 raw event 流,没有自动关联 pid 或 socket 地址,需配合
sk->num(端口)、sk->sport等字段做人工匹配;生产环境慎开,开销不小
真正的状态变迁不是日志式记录,而是内核内存中变量的实时改写。能观测到的,只有快照、计时器、系统调用入口、以及内核函数 trace 四种粒度——选哪种,取决于你手头的问题:是查当前卡在哪,还是复盘上次为什么断连。

















