为了获得特定接口的统计信息,已经提出的方法可以很好地工作。相反,我会尝试为您的第二个请求提供解决方案:“了解使用该带宽的程序将非常有帮助,但到目前为止,我还没有看到任何可以做到这一点的东西。”如先前建议的那样,nethogs打印进程特定的统计信息。据我所知,在/proc下没有
简单的方法来访问这些值,因此我将解释nethogs如何实现这一点。考虑具有pid PID的一个进程,nethogs首先检索由该进程打开的所有套接字的列表,列出/proc/PID/fd的内容:
➜ ~ [1] at 23:59:31 [Sat 15] $ ls -la /proc/21841/fd
total 0
dr-x------ 2 marco marco 0 Nov 15 23:41 .
dr-xr-xr-x 8 marco marco 0 Nov 15 23:41 ..
lrwx------ 1 marco marco 64 Nov 15 23:42 0 -> /dev/pts/15
l-wx------ 1 marco marco 64 Nov 15 23:42 1 -> /dev/null
lrwx------ 1 marco marco 64 Nov 15 23:41 2 -> /dev/pts/15
lrwx------ 1 marco marco 64 Nov 15 23:42 4 -> socket:[177472]
这里只有一个套接字,177472是inode号。我们可以找到各种类型的套接字:TCPv4、TCPv6、UDP、netlink。在这种情况下,我只考虑TCPv4。
一旦收集到所有的inode号,每个套接字都会被分配一个唯一的标识符,即(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)。当然,与PID的配对也会被存储。元组(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)可以通过读取/proc/net/tcp(对于TCPv4)来检索。在这种情况下:
➜ ~ [1] at 0:06:05 [Sun 16] $ cat /proc/net/tcp | grep 177472
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
38: 1D00A8C0:1F90 0400A8C0:A093 01 00000000:00000000 00:00000000 00000000 1000 0 177472 1 f6fae080 21 4 0 10 5
地址表示为IP:PORT,其中IP表示为4字节LE数字。然后可以构建一个
key->value
结构,其中键是
(IP_SRC, PORT_SRC, IP_DEST, PORT_DEST)
,值是PID。
此时,nethogs使用libpcap捕获所有网络流量。当它检测到TCP数据包时,它会尝试将元组
(IP_SRC_PACKET, PORT_SRC_PACKET, IP_DEST_PACKET, PORT_DEST_PACKET)
与表中的所有连接进行匹配。当然,它必须尝试交换SRC和DEST,因为数据包可能是传入的(DL)或传出的(UL)。如果它匹配了一个连接,则检索该连接所属进程的PID,并将TCP负载的大小添加到TX或RX计数器中。每次捕获数据包时更新字节数,就可以轻松计算每个进程的传输速度。
理论上,这可以使用pypcap在Python中实现,尽管需要一些工作。我尝试过实现一些东西,但速度非常慢,需要更多的工作才能使用。我只监视一个PID,一个连接,没有更新连接表,但是在3MB/s以上,我的脚本无法跟上网络流量。
正如您所看到的,这并不是很简单。解析已有工具的输出可能会导致更好的解决方案,并且可能会节省大量工作。
nload -m wlan0 | do_stuff.py
。 - Leonnethogs
可以为您完成这项任务。 - Leon