如何在不使用lsof或netstat的情况下将网络连接绑定到PID?

9
有没有一种方法可以将网络连接与PID(进程ID)绑定,而不需要派生到lsof或netstat?
目前,使用lsof来轮询哪些连接属于哪个进程ID。 但是,在繁忙的主机上,lsof或netstat可能会非常昂贵,并且希望避免必须派生这些工具。
有没有类似于/proc/$pid的地方可以查找此信息?我知道通过检查/proc/net可以找到网络连接,但无法弄清如何将其绑定回pid。在/proc/$pid中,似乎没有任何网络信息。
目标主机为Linux 2.4和Solaris 8至10。如果可能,请提供Perl解决方案,但愿意使用C / C ++。
附加说明:
我想强调这里的目标是将网络连接与PID绑定。 获得一个或另一个是微不足道的,但以低成本的方式将两者结合起来似乎很困难。 感谢迄今为止的答案!
6个回答

8

我不知道您需要多少频繁地轮询,或者您所说的“昂贵”是什么意思,但是使用正确的选项,netstatlsof都比默认配置下运行得更快。
例如:

netstat -ltn

该命令只显示监听TCP套接字,省略了默认开启的(缓慢的)名称解析

lsof -b -n -i4tcp:80

在端口80上,它省略所有blocking操作、name解析并仅限于选择IPv4 tcp套接字。


1
在Linux上,'netstat -tnp' 给了我想要的结果。'p' 给了我pid信息,而且速度相当快。但是我希望避免使用fork调用netstat来获取这些信息。同样的问题也出现在'lsof'中,虽然我已经让它快速工作,但仍希望避免fork。 - jac_no_k

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

1

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


1
我之前瞄了一眼netstat。我相当确定它只是在/proc中穿梭,建立连接缓存。我认为那里没有任何魔法。 - Duck
@Duck 不需要魔法 :-) 而且它仍然是复制代码的好参考,因为他强调不想在子进程中运行 netstat。 - lothar

1

针对Linux系统,可以查看/proc/net目录(例如,cat /proc/net/tcp列出TCP连接)。我不确定Solaris系统是否适用。

更多信息这里

我猜netstat基本上使用了完全相同的信息,所以我不知道您能否大大加速它。请务必尝试使用netstat的“-an”标志来实时地不解析IP地址为主机名(因为这可能需要进行很多DNS查询而耗费时间)。


我们找到了一种通过查看/proc/net/tcp来确定pid的迂回方法。从“tcp”中获取uid和socket。然后遍历/proc/*,其中所有者是uid并且“fd”包含相同的socket。不幸的是,这在Solaris上不起作用。此外,我希望有一种不需要搜索/proc文件系统的解决方案。 - jac_no_k

1

最简单的事情是

strace -f netstat -na

在Linux上(我不知道Solaris),这将为您提供所有系统调用的日志。这是大量输出,其中一些将是相关的。查看它正在打开的/proc文件系统中的文件。这应该引导您了解netstat如何运作。顺便说一句,ltrace将允许您通过c库执行相同的操作。在此情况下对您不是很有用,但在其他情况下可能会很有用。
如果从那里不清楚,请查看源代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接