0

我是 C 网络编程的新手。我正在尝试为我的 conky 编写一个补丁来显示类似“netstat -pan --inet”的内容。Conky 的内置 tcp_mon 不包含进程名称。

最初我使用 netstat 和 awk 执行此操作,但使用这种方法我的脚本性能受到影响。所以我试图直接用C编码。netstat 的输出看起来像这样

Proto Recv-Q Send-Q Local Address           Foreign Address         State           PID/Program name    
tcp        0      0 0.0.0.0:17500           0.0.0.0:*               LISTEN         1042/dropbox        
tcp        0      0 192.168.0.1:3333        24.244.4.104:2222     ESTABLISHED    1225/chrome 

我有兴趣显示最后一列“PID/程序”我查看了套接字库,但我没有遇到任何关于进程名称或其 pid 的信息。顺便说一句,我在 Archlinux 上

所以我的问题是 1)我在看正确的地方吗?如果没有,在哪里?2)有没有更好的方法来做到这一点?

4

2 回答 2

0

至少在使用最近的 Linux 内核时,可以使用以下命令读出进程的名称(由对 OP 的注释定义)prctl()

#include <sys/prctl.h>
#include <stdio.h> /* for perror() */
...

char [17] = proc_name = {0}; /* the buffer provided shall at least be 16+1 bytes long */

if (-1 == prctl(PR_GET_NAME, proc_name, ...))
  perror("prctl(PR_GET_NAME, ...)"); 

应该知道最多返回 16 个字节,并且在这种情况下不会添加尾随0终止符。所以初始化要传递prctl()给所有人的字符数组0是个好主意。

也可以通过执行以下操作来设置此“名称”:

char [17] = proc_name = "new name"; /* The name will be truncated to 16 bytes */

if (-1 == prctl(PR_SET_NAME, proc_name, ...))
  perror("prctl(PR_SET_NAME, ...)"); 

的手册页的相关摘录prctl()是:

PR_SET_NAME(自 Linux 2.6.9 起)

使用 (char *) arg2 指向的位置中的值设置调用进程的进程名称。该名称最长可达 16 个字节,如果它包含较少的字节,则应以空字符结尾。

PR_GET_NAME(自 Linux 2.6.11 起)

返回调用进程的进程名称,在 (char *) arg2 指向的缓冲区中。缓冲区应允许最多 16 个字节的空间;如果返回的字符串短于该字符串,则返回的字符串将以空字符结尾。


请注意,上述“进程名称”值与进程的命令行不同。后者可以在/proc/<pid>/cmdline.

它作为0终止字符数组存储在那里。


一个方便的读出/proc方法是使用PROCPS 提供的工具包


更新

在查看netstat's sources 后,它似乎从/proc/<pid>/cmdline. 相关的 pid 来自于扫描/proc/<pid>/fd寻找与socket:*.

于 2013-06-17T06:51:26.350 回答
0

假设是 Linux,我认为你必须进入 /proc/*/fd 并四处寻找

于 2013-06-16T01:11:22.017 回答