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

10

我正在寻找一种在Linux和MacOSX上使用C语言获取网络统计信息的方法。具体而言,我需要监控系统上每个网络适配器上传和下载的字节数-我不需要进行数据包检查或区分协议,只需要一个“总字节数”计数器,我可以在间隔时间内轮询即可。在Windows中,我可以通过iphlpapi.dll库使用GetIfTable(列出网络适配器)和GetIfEntry(读取统计信息)来完成此操作,但我找不到Linux / OSX的等效方法。我的C语言知识相当基础,因此希望能够有一个简单的解决方案。任何帮助都将不胜感激!


从我目前所了解的情况来看,你无法在两个平台上使用通用代码。Linux似乎使用文件系统来保留这些信息,而查询系统的常规方法是读取文件。在OSX上,这些信息存储在内存和晦涩的文件中。 - Armand
3个回答

25

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”文件。 - virata
我知道这是为OSX设计的,但我需要在iOS设备上运行。有什么想法吗? - virata
做得很好。我喜欢你也提供了一个Objective-C的解决方案。 - Armand
我该如何用Bash做到这一点? - noɥʇʎԀʎzɐɹƆ
谢谢这个例子!我将NSAutoreleasePool更改为std :: vector以用于缓冲区,将其转换为了C ++。 - Hal Canary

1

在Linux系统上:

  • 低级别: 检查 /sys/class/net/eth0/statistics/
  • 稍微高级一些: ip -s link show eth0
  • 图形化界面: iftop
  • 交互式界面: iptraf

5
标题是OSX。前两个在OSX上不起作用。底部的两个也不适合这个问题,因为它们是图形化和交互式的。 - Purrell
2
标题和问题正文都提到了Linux和OSX。这是关于Linux部分的内容。 - Javier

1

我不知道如何在OSX中实现,但是在linux中,请查看/proc/net/dev。

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

编辑:

我没看完你的问题。这篇文章应该能帮助你开始使用/proc,并有一个关于/proc/net/dev的部分。

此外,要列出接口,您可以使用ioctlSIOCGIFCONF选项调用。您可以在谷歌上搜索一个优秀的代码示例,来遍历返回的数据。或者您可以直接从上面提到的/proc.net/dev数据中获取信息,这应该更容易。


或者,根据Javier的答案,在/sys/class/net/{your network interface}/statistics下查看文件,其中{your network interface}是您想要查看的网络接口的名称,例如第一个以太网接口的eth0。 sysfs(在/sys上)比procfs(在/proc上)更新。 - user862787

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接