Rust如何不依赖ss/netstat等命令获取本机开放TCP连接
Rust获取本机开放TCP连接的实现方案
可用Rust库
以下库均不依赖ss、netstat等外部命令,直接通过系统接口获取数据:
netstat2:跨平台封装库,Linux下直接解析procfs文件系统数据,Windows、macOS下分别调用对应系统原生网络枚举API,可直接获取TCP连接的本地/远端地址端口、连接状态、关联进程PID等信息,开箱即用。procfs:专门用于解析Linux proc虚拟文件系统的库,内置了/proc/net/tcp、/proc/net/tcp6节点的解析逻辑,可直接拿到所有TCP连接的基础信息,配合进程fd目录的解析能力即可关联到对应持有连接的进程,适合只需要支持Linux平台的场景。pnet:底层网络开发库,提供了基础的网络字节序处理、套接字操作封装,如果你需要完全自定义枚举逻辑,可以基于它自行实现procfs解析或netlink通信逻辑,灵活度最高。
Libc层原生原语/系统接口
Linux下不存在单个libc函数可以直接返回全量TCP连接列表,内核通过两类原生接口暴露连接数据,均不需要依赖外部二进制程序,可直接通过libc系统调用实现:
- procfs读取方式:通过
open、read等基础文件操作类系统调用,读取/proc/net/tcp(IPv4 TCP连接表)、/proc/net/tcp6(IPv6 TCP连接表)的内容,按照内核规定的文本格式逐行解析,即可提取到连接的十六进制编码IP、端口、连接状态(监听、建立连接、关闭等待等)、socket inode编号。如果需要关联连接对应的进程,可遍历/proc/[pid]/fd目录下的所有文件描述符,匹配socket类型fd对应的inode值即可定位到对应进程。 - netlink套接字方式:通过
socket系统调用创建AF_NETLINK类型的套接字,绑定NETLINK_INET_DIAG协议组,按照内核要求的格式发送连接查询请求,之后通过recv调用读取内核返回的结构化响应数据,即可拿到全量TCP连接的详细参数,包括连接状态、地址端口、关联进程ID、套接字配置参数等。这也是ss命令底层使用的实现方式,性能比解析procfs文本更高。
注意:以上两类原生实现逻辑完全运行在自身程序进程内,不需要fork执行任何外部系统命令,不存在绑定外部二进制的兼容性问题。
内容的提问来源于stack exchange,提问作者Saurav Banka
相关产品推荐
相关产品推荐

