9

有没有办法在不分叉到 lsof 或 netstat 的情况下将网络连接绑定到 PID(进程 ID)?

目前 lsof 用于轮询哪些连接属于哪个进程 ID。但是 lsof 或 netstat 在繁忙的主机上可能会非常昂贵,并且希望避免使用这些工具。

是否有类似于 /proc/$pid 的地方可以查找此信息?我通过检查 /proc/net 知道网络连接是什么,但无法弄清楚如何将其与 pid 联系起来。在 /proc/$pid 中,似乎没有任何网络信息。

目标主机是 Linux 2.4 和 Solaris 8 到 10。如果可能的话,Perl 中的解决方案,但我愿意做 C/C++。

补充说明:

我想强调这里的目标是将网络连接绑定到 PID。获得其中一个是微不足道的,但是以低成本的方式将两者结合起来似乎很困难。感谢您到目前为止的答案!

4

6 回答 6

8

我不知道您需要多久进行一次轮询,或者您所说的“昂贵”是什么意思,但是两者都有正确的选项netstat并且lsof运行速度比默认配置快得多。
例子:

netstat -ltn

仅显示l istening t cp套接字,并省略默认打开的(慢)名称分辨率。

lsof -b -n -i4tcp:80

省略所有b锁定操作、名称解析,并将选择限制为端口 80 上的 IPv4 tcp 套接字

于 2009-05-08T06:11:43.903 回答
6

在 Solaris 上,您可以使用它pfiles(1)来执行此操作:

# ps -fp 308 
     UID   PID  PPID   C    STIME TTY         TIME CMD
    root   308   255   0 22:44:07 ?           0:00 /usr/lib/ssh/sshd
# pfiles 308 | egrep 'S_IFSOCK|sockname: '
   6: S_IFSOCK mode:0666 dev:326,0 ino:3255 uid:0 gid:0 size:0
        sockname: AF_INET 192.168.1.30  port: 22

对于 Linux,这更复杂(可怕):

# pgrep sshd
3155
# ls -l /proc/3155/fd | fgrep socket
lrwx------ 1 root root 64 May 22 23:04 3 -> socket:[7529]
# fgrep 7529 /proc/3155/net/tcp 
   6: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7529 1 f5baa8a0 300 0 0 2 -1            

00000000:00160.0.0.0:22。这是来自的等效输出netstat -a

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
于 2009-05-22T21:47:00.263 回答
1

你为什么不看一下netstat的源代码,看看它是如何获取信息的?它是开源的。

于 2009-05-08T05:40:34.853 回答
1

对于 Linux,查看/proc/net目录(例如,cat /proc/net/tcp列出您的 tcp 连接)。不确定 Solaris。

更多信息在这里

我猜 netstat 基本上使用了完全相同的信息,所以我不知道你是否能够加快速度。请务必尝试使用 netstat '-an' 标志以不实时将 ip 地址解析为主机名(因为由于 dns 查询,这可能需要很多时间)。

于 2009-05-08T05:56:21.100 回答
1

最简单的做法是

strace -f netstat -na

在 Linux 上(我不了解 Solaris)。这将为您提供所有系统调用的日志。这是很多输出,其中一些是相关的。查看它正在打开的 /proc 文件系统中的文件。这应该会引导您了解 netstat 是如何做到的。不雅地,ltrace 将允许您通过 c 库做同样的事情。在这种情况下对您没有用,但在其他情况下可能很有用。

如果不清楚,请查看源代码。

于 2009-05-08T06:04:58.430 回答
0

看看这些彻底探索可用选项的答案:

于 2010-10-30T04:08:35.803 回答