【问题标题】:How to tie a network connection to a PID without using lsof or netstat?如何在不使用 lsof 或 netstat 的情况下将网络连接绑定到 PID?
【发布时间】:2009-05-08 05:08:28
【问题描述】:

有没有一种方法可以将网络连接绑定到 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。获得其中一个是微不足道的,但是以低成本的方式将两者结合起来似乎很困难。感谢您到目前为止的答案!

【问题讨论】:

    标签: linux networking solaris pid


    【解决方案1】:

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

    netstat -ltn
    

    仅显示 l正在侦听 tcp 套接字,并忽略默认开启的(慢)name 分辨率。

    lsof -b -n -i4tcp:80
    

    省略所有b锁定操作,name 分辨率,并将选择限制为端口 80 上的 IPv4 tcp 套接字。

    【讨论】:

    • 在 Linux 上的“netstat -tnp”给了我想要的东西。 'p' 给了我 pid,而且确实很快。但我希望避免分叉到 netstat 来获取这些信息。与 'lsof' 相同,我已经让它工作得非常快,但想避免分叉。
    【解决方案2】:

    在 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
    

    【讨论】:

      【解决方案3】:

      你为什么不看一下netstat的源代码,看看它是怎么得到信息的?它是开源的。

      【讨论】:

      • 不久前我看了一眼 netstat。我很确定它只是通过 /proc 建立连接缓存。我不认为那里有什么魔法。
      • @Duck 不需要魔法 :-) 它仍然是复制代码的一个很好的参考,因为他指出不想在子进程中运行 netstat。
      【解决方案4】:

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

      更多信息here

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

      【讨论】:

      • 我们通过查看 /proc/net/tcp 找到了一种确定 pid 的方法。从 'tcp' 获取 uid 和套接字。然后遍历所有者为 uid 且“fd”包含相同套接字的 /proc/*。不幸的是,这在 Solaris 中不起作用。我还希望有一个不需要通过 /proc 文件系统进行搜索的解决方案。
      【解决方案5】:

      最简单的方法是

      strace -f netstat -na
      

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

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

      【讨论】:

        【解决方案6】:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-18
          • 1970-01-01
          • 2019-03-21
          相关资源
          最近更新 更多