2

我正在尝试制作一个 TCP 性能监控工具,我要提取的主要值tcpi_rtt 来自 tcp_info

对于进程内套接字,这可以像getsockopt(socket.SOL_TCP, socket.TCP_INFO)在 python中一样获得

但是外部过程呢?对于 TCP 连接,在具有 root 的 python 下,我尝试os.open(/proc/XXXX/fd/4)了套接字 inode 但失败了OSError: [Errno 6] No such device or address:。此方法仅适用于常规 fd 或 stdin/stdout。

有什么通用的方法可以在 linux 上查看其他进程的 tcp_info 吗?

4

1 回答 1

0

没有我知道的 python 工具可以满足您的要求,也没有一种简单的方法可以让我想到自己解析 proc 目录。因此,您可以自己实现ss 命令的纯 python 版本(或者至少弄清楚它如何根据 /proc/<pid>/net/* 中的信息计算 RTT),或者解析它的输出。我更像是一个 bash 人,所以这就是我拼凑起来以获得 (RTT,PID) 对列表的内容:

#!/usr/bin/python
from subprocess import check_output as co

co("ss -tp > ss.out", shell=True)
rtts = co("cat ss.out | grep ESTAB | awk '{print $4}' | xargs -I {} ss -i 'src {}' | grep \"rtt:\" | awk '{print $4}' | cut -d : -f 2 | cut -d / -f 1", shell=True)
pids = co("cat ss.out | grep ESTAB | awk '{print $6}' | cut -d , -f 2", shell=True)

print zip(rtts.split('\n'), pids.split('\n'))

在 ss 命令中,-t 表示显示 TCP 连接,-p 表示打印进程 (PID) 信息。使用 -e 选项,您还可以获得 inode 编号,您可以使用它来确定 /proc/XXXX/fd/ 中的文件描述符编号。例如,我有进程 31117 在我的机器上运行,文件描述符编号为 11,对应于 inode 编号为 31159 的套接字:

# ls -lah /proc/31117/fd/11
lrwx------ 1 root root 64 Dec 10 19:08 /proc/31117/fd/11 -> socket:[31159]

您无法“打开”像 /proc/pid/fd/4 这样的套接字文件的原因是因为这些都是指向不存在文件的链接。您可以从它们那里获得的唯一信息是套接字的名称(inode 号)。

于 2013-12-11T01:22:34.397 回答