如何在 linux/Mac OSX 中获取网络适配器统计信息?

Posted

技术标签:

【中文标题】如何在 linux/Mac OSX 中获取网络适配器统计信息?【英文标题】:How to get network adapter stats in linux/Mac OSX? 【发布时间】:2010-11-10 17:43:57 【问题描述】:

我正在寻找一种在 Linux 和 MacOSX 上用 C 语言获取网络统计信息的方法。具体来说,我需要监控从系统上每个网络适配器上传和下载的字节数——我不需要进行数据包检查,也不需要区分协议,只需一个“总字节”计数器,我可以每隔一段时间轮询一下没事的。在 Windows 中,我可以通过 GetIfTable(列出网络适配器)和 GetIfEntry(读取统计信息)使用 iphlpapi.dll 库来执行此操作,但我找不到 Linux/OSX 等效项。我对 C 的了解是相当基础的,所以我会很感激一个不太涉及的解决方案。任何帮助将不胜感激!

【问题讨论】:

从我目前发现的情况来看,您将无法在两个平台上使用通用代码。看来Linux使用文件系统来保留这些信息,查询系统的正常方法是读取文件。在 OSX 上,信息保存在内存和模糊文件中。 【参考方案1】:

Darwin netstat 源代码使用 sysctl。 下面是一些在 OSX 上打印输入输出字节数的代码:

#import <Foundation/Foundation.h>
#include <sys/sysctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/route.h>

int main (int argc, const char * argv[]) 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int mib[] = 
        CTL_NET,
        PF_ROUTE,
        0,
        0,
        NET_RT_IFLIST2,
        0
    ;
    size_t len;
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) 
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    
    char *buf = (char *)malloc(len);
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) 
        fprintf(stderr, "sysctl: %s\n", strerror(errno));
        exit(1);
    
    char *lim = buf + len;
    char *next = NULL;
    u_int64_t totalibytes = 0;
    u_int64_t totalobytes = 0;
    for (next = buf; next < lim; ) 
        struct if_msghdr *ifm = (struct if_msghdr *)next;
        next += ifm->ifm_msglen;
        if (ifm->ifm_type == RTM_IFINFO2) 
            struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
            totalibytes += if2m->ifm_data.ifi_ibytes;
            totalobytes += if2m->ifm_data.ifi_obytes;
        
    
    printf("total ibytes %qu\tobytes %qu\n", totalibytes, totalobytes);
    [pool drain];
    return 0;

【讨论】:

这在模拟器上运行良好。但在设备上给出错误。错误是 - /Users/praveendala/Desktop/all in one3/app2/app2/main.m:13:10: 致命错误:找不到“net/route.h”文件。 我知道这是针对 OSX 的。但我需要在 ios 设备上运行。有什么想法吗? 做得很好。我也喜欢你提供一个 Objective-C 解决方案。 如何用 bash 做到这一点? 感谢这个例子!我通过将 NSAutoreleasePool 更改为缓冲区的 std::vector 将其转换为 C++。【参考方案2】:

我不会在 OSX 上说话,但在 linux 上看看 /proc/net/dev。

如果您执行“cat /proc/net/dev”,您应该会看到包括“bytes”在内的统计信息 - 接口传输或接收的数据字节总数。您可以在自己的程序中读取该文件。

编辑:

我没有阅读你的整个问题。 This article 应该可以帮助您开始使用 /proc,并且有一个关于 /proc/net/dev 的部分。

此外,要列出您可以使用SIOCGIFCONF 选项调用ioctl 的接口。你可以在谷歌上找到一个关于如何循环返回数据的不错的代码示例。或者你可以简单的从上面提到的/proc.net/dev数据中拉出来,应该会更简单。

【讨论】:

或者,根据 Javier 的回答,查看/sys/class/net/your network interface/statistics 下的文件,其中your network interface 是您要查看的网络接口的名称,例如eth0 用于第一个以太网接口。 sysfs(/sys)比 procfs(/proc)更新。【参考方案3】:

在 Linux 上:

低电平:检查/sys/class/net/eth0/statistics/ 略高:ip -s link show eth0 图形:iftop 互动:iptraf

【讨论】:

问题标题是 OSX。前两个在 OSX 上不起作用。后两个也不适合提问,因为图形和交互。 问题的标题和正文都提到了 Linux 和 OSX。这是关于 Linux 部分的

以上是关于如何在 linux/Mac OSX 中获取网络适配器统计信息?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取当前使用的网络适配器

如何获取网络适配器索引?

基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境

如何在 OSX 上的单独进程中读取网络摄像头?

如何通过 .NETCore 获取 Linux,Mac 的硬件信息?

如何在 OSX 环境中访问本地网络上的网站