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

时间:2009-07-14 17:19:39

标签: c linux macos api networking

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

3 个答案:

答案 0 :(得分:21)

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;
}

答案 1 :(得分:2)

Linux上的

  • 低级别:检查/sys/class/net/eth0/statistics/
  • 略高一级:ip -s link show eth0
  • 图形:iftop
  • 互动:iptraf

答案 2 :(得分:2)

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

如果你做'cat / proc / net / dev',你应该看到包括'bytes'在内的统计信息 - 接口发送或接收的数据的总字节数。您可以在自己的程序中阅读该文件。

编辑:

我没有读完你的整个问题。 This article应该帮助你开始使用/ proc并在/ proc / net / dev上有一个部分。

此外,要列出接口,您可以使用ioctl选项调用SIOCGIFCONF。您可以通过Google获取有关如何循环返回数据的代码示例。或者你可以简单地将它从上面提到的/proc.net/dev数据中拉出来,这应该更容易。