【问题标题】:how do I find out what program's on the other end of a local socket?如何找出本地套接字另一端的程序?
【发布时间】:2010-10-23 16:13:16
【问题描述】:

strace 告诉我,我的 Linux 系统上的一个进程正在使用文件描述符为 10 的套接字。lsof 告诉我这是一个 inode 11085 的 unix 套接字,netstat 进一步告诉我 inode 11085 是一个流套接字,并且它已连接。

鉴于此进程没有任何其他线程,因此系统上必须有另一个进程连接到此套接字的另一端。我如何知道它是什么?

更新:

lsof 作者here 提供了一些启发。从本质上讲,Linux 似乎只是不提供这些信息。

【问题讨论】:

  • 即使没有线程,进程也可以拥有套接字的两端。
  • 是的。但在这种情况下,它正在轮询()套接字并定期唤醒,所以一定有其他东西在唤醒它。

标签: linux debugging sockets


【解决方案1】:

netstat -p 有帮助吗?

来自手册页:

  -p,
  --program Show the PID and name of the program to which each socket belongs.

【讨论】:

  • 不幸的是,这是busybox netstat,所以它不支持-p。但是节点11085无论如何只在netstat输出中出现一次,所以它似乎只属于我已经知道的进程。
  • @daf 你应该在你的问题中提到busybox的使用(也可能在标签中)
  • Busybox 确实有一个配置选项来支持-p 开关。请参阅选项 CONFIG_FEATURE_NETSTAT_PRG,通过 Networking Utilities → netstat → Enable PID/Program name output 在busybox menuconfig 中选择。
【解决方案2】:

如果由于某种原因您无法使用适当的 lsof 和 netstat 选项,您还可以执行以下操作:

find /proc -lname '*11085*' 2> /dev/null

【讨论】:

  • 狡猾!由于系统只有busybox find,所以-lname不起作用,但我们可以模拟它:$ for i in find /proc -type l;阅读链接 "$i" | grep -q 11085 && echo "$i"; done /proc/1892/task/1892/fd/10 /proc/1892/fd/10 所以,只有原来的进程出现了。
【解决方案3】:

lsof | grep 11085

lsof 应该以 root 身份执行。

我一直在我的 Linux 系统上试验 lsof,lsof -U 显示 NODE 列下的所有数字都是唯一的。

【讨论】:

    【解决方案4】:

    这个怎么样:grep 11085 /proc/net/unix。假设在您感兴趣的inode所在的行上存在一个非空路径,grep/proc/net/unix 中的该路径找到连接另一端的inode,然后使用@efficientjelly 的方法将另一个 inode 映射到 pid

    这里的一个关键点是两个连接的套接字都将具有不同的 inode 编号。

    【讨论】:

    • 狡猾!我不知道/proc/net/unix。遗憾的是,没有与此套接字关联的路径。
    【解决方案5】:

    看起来如果你真的很绝望,你可以使用一些内核调试器直接从 Linux 内核内存中获取这些信息。使用 RHEL5 的“崩溃”工具:

    • 获取未压缩的vmlinux 映像(例如,安装kernel-debuginfo rpm,或从该rpm 中提取vmlinux 文件)
    • 运行crash /path/to/vmlinux
    • net -s 12345 列出PID 12345 的所有套接字
    • 找到有趣的套接字(必须是家庭/类型UNIX:STREAM),并注意它的SOCK 值:
      • PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
      • FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
      • 36 cadd0240 c8a64040 UNIX:STREAM
    • 你现在有了这个套接字的unix_sock struct的地址
      • 基本上unix_sock.peer.name是socket另一端的名字结构
      • 用:p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name 打印

    很遗憾,这些信息没有直接导出到用户空间。

    【讨论】:

      【解决方案6】:

      我观察到:

      在客户端调用 connect()fd 的 Inode 始终比您从服务器端调用 accept() 返回的 Inode 大一。

      我的 prog 的示例输出:

      client_fd=4
      /proc/4436/fd/4
      inode=3072
      is socket
      node: 3072 socket: /tmp/unix.socket
      f0be8960: 00000003 00000000 00000000 0001 03  3072 /tmp/unix.socket
      
      /proc/9293/fd/43
      fd:43
      inode=3073
      is socket
      node: 3073 socket: 
      f0be81e0: 00000003 00000000 00000000 0001 03  3073
      

      /proc/net/unix 中并未显示绑定路径。

      YMMV 和我还没有研究过底层机制。

      【讨论】:

      • +1,不幸的是,这似乎是获得结果的唯一方法......!
      • (抱歉,我评论太快了,我的电脑上没有验证...)
      • 大部分时间都有效,但不可靠(见my answer
      【解决方案7】:
      ss -p
      

      会告诉你的。 (前提是套接字不属于内核本身。)

      【讨论】:

      • 在 Debian 上,/usr/bin/ssiproute2 包中
      • 这在我的情况下没有帮助,但标记为正确,因为它很简单并且适用于 IP 和 unix 套接字。
      • 问题是关于本地套接字的。 -1
      • 糟糕,我不能给你两颗星。这个问题几个月以来一直在挑战我......现在我可以完成我的指南linuxintro.org/wiki/Strace
      【解决方案8】:

      我写了一个tool,它使用gdb method 可靠地获取套接字对等信息,不需要内核调试符号。

      要让进程连接到给定的套接字,请将 inode 号传递给它:

      # socket_peer 11085
      3703 thunderbird 
      

      要一次找出所有进程,请使用netstat_unix,它会在 netstat 的输出中添加一列:

      # netstat_unix
      Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
      unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
      unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
      unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
      unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
      unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
      unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
      ...
      

      如果您需要易于解析的输出,请尝试 netstat_unix --dump
      详情请见https://github.com/lemonsqueeze/unix_sockets_peers

      关于信息,inode +1/-1 hack 不可靠。它大部分时间都可以工作,但如果你运气不好,它会失败或(更糟)返回错误的套接字。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 2011-05-02
        • 2016-03-27
        • 2014-03-05
        • 1970-01-01
        • 2010-12-03
        • 2018-06-10
        相关资源
        最近更新 更多