You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux 4.15内核TCP连接存储位置及端口查询套接字技术问询

Linux 4.15内核TCP套接字存储与相关内核函数答疑

咱们一步一步来拆解你的三个问题,都是TCP栈内核实现里的关键细节:

1. 已建立TCP连接的存储位置

在Linux 4.15中,完成三次握手、处于ESTABLISHED状态的TCP套接字(对应struct sock结构体),是挂载在**tcp_hashinfo结构体**的established哈希链表上的。为了减少多CPU场景下的锁竞争,内核还为每个CPU核心分配了独立的tcp_established_hash(属于per_cpu变量),每个套接字会根据自身的四元组(本地IP+端口、远端IP+端口)计算出哈希值,进而链入对应的哈希桶中。

你可以通过inet_sk(sock)->inet_num(本地端口)、inet_sk(sock)->inet_daddr(本地IP)等字段,从哈希链中匹配到具体的已建立连接。

2. 未完成四次挥手的TCP连接存储位置

这得分不同的关闭状态来区分:

  • FIN_WAIT1/FIN_WAIT2/CLOSE_WAIT/LAST_ACK状态:这些还在等待对方报文的套接字,依然留在tcp_hashinfo的established哈希链上。只有当它们完成所有关闭步骤,或者超时后,才会被移走或销毁。
  • TIME_WAIT状态:当连接进入TIME_WAIT(主动关闭方收到最终ACK后),对应的套接字会被转移到tcp_hashinfo的timewait_hash哈希表(由tw_bucket结构体组成)中。这个表是专门用来存放等待2MSL时间的连接,避免旧连接的报文干扰新连接,同时也能减轻主哈希链的负担。

3. 仅根据监听端口返回已打开套接字的内核函数

内核里没有直接提供“仅根据监听端口返回所有关联套接字”的现成函数,但你可以基于现有接口实现这个逻辑:

  • 找监听套接字本身:可以调用inet_lookup_listener函数,传入IPPROTO_TCP、本地IP(如果要匹配所有IP可以传INADDR_ANY)和目标端口,就能找到对应的监听套接字。
  • 找该端口下的已建立连接:需要遍历tcp_hashinfo的established哈希链,逐个检查每个sock的inet_sk(sock)->inet_num是否等于目标端口。内核提供了tcp_for_each_sk宏来辅助遍历,但要注意加锁(比如tcp_hashinfo的全局锁或者单个哈希桶的锁),避免并发访问导致的问题。

另外,用户态的ss、netstat工具就是通过读取/proc/net/tcp文件获取这些信息的,而这个文件的内容正是内核遍历上述哈希表后生成的。


内容的提问来源于stack exchange,提问作者Random

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:12:43