Windows原生C如何按网卡获取IPv4带宽使用统计?求指引
原生C环境下获取单网卡收发字节数的解决方案
我之前也碰到过这个痛点,GetIpStatistics确实只能拿到全局的IP统计数据,没法按单网卡拆分。不过Windows API里其实有专门的接口能实现这个需求,下面给你梳理两种可行的方案:
方法一:使用GetIfEntry2 API(推荐)
这是Windows Vista及以后系统支持的API,能直接获取指定网卡的详细统计信息,完全可以替代.NET里的BytesReceived和BytesSent。步骤很清晰:
- 枚举所有网卡接口:先用
GetAdaptersAddresses函数获取系统中所有网卡的基本信息(比如接口索引、友好名称等) - 获取单网卡统计数据:针对每个网卡的接口索引,调用
GetIfEntry2就能拿到该网卡的收发字节数等核心指标
代码示例
#include <iphlpapi.h> #include <stdio.h> #include <wchar.h> // 链接IP帮助库 #pragma comment(lib, "iphlpapi.lib") int main() { ULONG bufferSize = 0; // 先调用一次获取所需缓冲区大小 GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &bufferSize); PIP_ADAPTER_ADDRESSES pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)malloc(bufferSize); if (pAdapterAddresses == NULL) { printf("内存分配失败\n"); return 1; } if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddresses, &bufferSize) == NO_ERROR) { PIP_ADAPTER_ADDRESSES pCurrentAdapter = pAdapterAddresses; while (pCurrentAdapter != NULL) { MIB_IF_ROW2 ifRow = {0}; ifRow.InterfaceIndex = pCurrentAdapter->IfIndex; // 获取该网卡的统计数据 if (GetIfEntry2(&ifRow) == NO_ERROR) { wprintf(L"网卡名称: %s\n", pCurrentAdapter->FriendlyName); printf("累计接收字节数: %llu\n", ifRow.InOctets); printf("累计发送字节数: %llu\n", ifRow.OutOctets); printf("----------------------------------------\n"); } else { wprintf(L"获取网卡[%s]统计数据失败\n", pCurrentAdapter->FriendlyName); } pCurrentAdapter = pCurrentAdapter->Next; } } else { printf("枚举网卡失败\n"); } free(pAdapterAddresses); return 0; }
关键字段对应关系
ifRow.InOctets:完全对应.NET中的BytesReceived,是该网卡累计接收的总字节数ifRow.OutOctets:完全对应.NET中的BytesSent,是该网卡累计发送的总字节数
方法二:使用性能计数器(Performance Counters)
如果你的场景需要更丰富的网络指标(比如每秒收发速率),也可以通过Windows性能计数器来读取单网卡数据。核心是读取Network Interface类别下的Bytes Received和Bytes Sent计数器,不过这种方式需要处理网卡实例的匹配(每个网卡对应一个计数器实例),实现起来比GetIfEntry2稍复杂,适合需要多维度指标的场景。
注意事项
GetIfEntry2需要Windows Vista及以上系统支持,如果要兼容Windows XP,可以使用旧版的GetIfEntry函数(功能类似,但结构体字段有所不同)- 编译时必须链接
iphlpapi.lib库,否则会出现链接错误 - 程序一般普通用户权限即可运行,某些受限环境可能需要管理员权限
内容的提问来源于stack exchange,提问作者eKKiM
相关产品推荐
相关产品推荐

