首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux C 編程:解析 /proc/net/dev 實現 ifconfig 風格網卡流量統計

     編輯:關於C語言

Linux 下無需調用複雜的 ioctl/netlink,直接讀取 /proc/net/dev 即可獲取各網卡接收/發送字節數、包數、錯誤數等統計。本文提供完整 C 實現,解析文件格式、字段映射、單位換算,並給出可直接編譯運行的代碼。

/proc/net/dev 格式速覽

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  eth0: 123456  789    0    0    0     0          0         0      654321  456    0    0    0     0       0          0
    lo:  11111   22     0    0    0     0          0         0      11111   22     0    0    0     0       0          0
  • 前兩行為表頭,**數據從第 3 行開始**。
  • 每行:接口名: + 16 個數值(前 8 個 Receive,後 8 個 Transmit)。
  • 第 1 個字段 = 接收字節數(Rx Bytes),第 9 個字段 = 發送字節數(Tx Bytes)。

核心解析邏輯

long *get_iface_stats(const char *iface) {
    static long stats[2];  // [0]=Rx, [1]=Tx
    FILE *fp = fopen("/proc/net/dev", "r");
    if (!fp) return NULL;

    char line[512];
    fgets(line, sizeof(line), fp); // skip header 1
    fgets(line, sizeof(line), fp); // skip header 2

    while (fgets(line, sizeof(line), fp)) {
        char name[32];
        unsigned long rx_bytes, tx_bytes;
        // 格式: " eth0: 12345 678 ... 98765 432 ..."
        if (sscanf(line, " %31[^:]: %lu %*u %*u %*u %*u %*u %*u %*u %lu",
                   name, &rx_bytes, &tx_bytes) == 3) {
            if (strcmp(name, iface) == 0) {
                stats[0] = rx_bytes;
                stats[1] = tx_bytes;
                fclose(fp);
                return stats;
            }
        }
    }
    fclose(fp);
    return NULL;
}

完整可編譯程式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

long *get_iface_stats(const char *iface);  // 上文實現

int main(int argc, char *argv[]) {
    const char *iface = (argc > 1) ? argv[1] : "eth0";
    long *stats = get_iface_stats(iface);
    if (!stats) {
        fprintf(stderr, "Interface %s not found or read error\n", iface);
        return 1;
    }
    printf("%s: RX = %.2f MB, TX = %.2f MB\n",
           iface,
           stats[0] / (1024.0 * 1024.0),
           stats[1] / (1024.0 * 1024.0));
    return 0;
}

編譯與運行

gcc -Wall -o netstat netstat.c
./netstat eth0
# 輸出示例:eth0: RX = 12.34 MB, TX = 56.78 MB

進階擴展建議

  • 封裝為庫函數返回結構體 struct iface_stats { uint64_t rx_bytes, tx_bytes, rx_packets, tx_packets, rx_errs, tx_errs, ... }。
  • 定時輪詢計算速率:speed = (curr - prev) / interval。
  • 跨平台兼容:FreeBSD/macOS 使用 sysctl 或 libstatgrab。
  • 高性能場景:改用 netlink (NETLINK_ROUTE) 訂閱內核通知,避免輪詢開銷。

常見坑點

  1. 單位:/proc/net/dev 字段單位均為**字節**,非位/包。
  2. 計數器溢出:32 位計數器在高流量下會回卷,讀取時需用 64 位變量並處理回卷邏輯。
  3. 虛擬接口:docker0、veth* 等也會出現,按需過濾。
  4. 權限:讀取 /proc/net/dev 通常無需 root,但某些加固系統可能限制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved