C++在Windows平台获取指定网卡每秒收发比特数的实现方案问询
可行实现方案
方案1:使用Windows原生IP Helper API(首选)
该API是Windows官方提供的网络管理接口,直接返回64位网卡流量统计值,完全解决SNMP 32位计数器在千兆及以上带宽下的翻转问题,返回数据与任务管理器网络监控数据同源,精度最高。
实现步骤
- 引入依赖:头文件包含
#include <iphlpapi.h>,编译时链接iphlpapi.lib库 - 调用
GetIfEntry2函数,传入入参的网卡索引号(NET_IFINDEX类型),获取MIB_IF_ROW2结构体 - 从结构体中读取64位统计字段:
InOctets(累计接收字节数)、OutOctets(累计发送字节数)、LinkSpeed(网卡链路总带宽,单位bps) - 间隔固定时间(比如1秒)两次调用接口获取统计值,两次统计值的差值乘以8即为对应周期内的平均每秒收发比特数,和总带宽做比值即可得到网络利用率
核心代码示例
// 初始化结构体 MIB_IF_ROW2 ifRow = {0}; ifRow.InterfaceIndex = yourInputIfIndex; // 替换为传入的网卡索引号 // 获取网卡统计 DWORD ret = GetIfEntry2(&ifRow); if (ret == NO_ERROR) { ULONG64 recvBytes = ifRow.InOctets; ULONG64 sendBytes = ifRow.OutOctets; ULONG64 totalBandwidth = ifRow.LinkSpeed; }
注意事项
- 必须使用带
2后缀的新版接口,旧版GetIfEntry返回32位统计值,仍存在翻转问题 - 64位统计值溢出周期极长,千兆带宽下完全无需考虑溢出问题
方案2:使用WMI查询(开发效率更高)
如果轮询频率不高(比如间隔1秒以上),可以用WMI实现,无需自己做差值计算,直接读取格式化后的实时统计值即可。
实现逻辑
- 直接查询WMI类
Win32_PerfFormattedData_Tcpip_NetworkInterface - 通过
InterfaceIndex属性过滤指定索引号的网卡 - 读取
BytesReceivedPerSec、BytesSentPerSec属性,乘以8得到每秒收发比特数,读取CurrentBandwidth属性得到网卡总带宽,直接计算利用率即可
常见避坑点
- 单位转换时注意:1字节=8比特,不要直接用字节数作为比特数计算,结果会出现8倍误差
- 枚举网卡匹配索引号时,注意区分物理网卡和虚拟网卡,可通过
MIB_IF_ROW2的Type字段过滤掉回环、隧道等虚拟接口
内容的提问来源于stack exchange,提问作者chris-p-tech
相关产品推荐
相关产品推荐

