最可靠方式是调用getiftable2获取ifinoctets/ifoutoctets,配合queryperformancecounter精准采样1秒差值计算速率,全程用int64防回绕并检查接口状态,需调用freemibtable释放内存。

用 GetIfTable2 获取适配器基础信息和实时字节数
Windows 上最可靠的方式是调用 GetIfTable2(IPv6-aware,支持千兆以上速率),它返回每个接口的 ifInOctets 和 ifOutOctets——也就是累计接收/发送字节数。这不是“瞬时速率”,但配合两次采样差值就能算出真实网速。GetIfTable2 比旧版 GetIfTable 更稳定,不会漏掉虚拟网卡(如 WSL2、DockerNAT),也避免了 GetPerfCounterData 那种依赖性能计数器服务开启的问题。
注意点:
-
GetIfTable2返回的是PMIB_IF_TABLE2,需用FreeMibTable释放内存,否则每次调用都泄漏 - 某些低权限进程(如被 UAC 限制的控制台)可能拿不到物理网卡数据,建议以普通用户权限运行,无需管理员
- 接口状态为
IF_OPER_STATUS_UP才值得监控;IF_OPER_STATUS_DOWN或IF_OPER_STATUS_NOTPRESENT的直接跳过
两次采样间隔取 1 秒,用 QueryPerformanceCounter 控制精度
用 sleep(1000) 不够准:系统调度延迟可能让实际间隔变成 1050ms,导致速率计算偏差超 5%。尤其在高负载机器上,std::this_thread::sleep_for 也会漂移。更稳妥的是用 QueryPerformanceCounter 做自适应等待——记录起始时间戳,循环检查是否已过 1000ms,中间用 SwitchToThread 让出 CPU。
关键逻辑示例:
LARGE_INTEGER start, freq, now;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
while (true) {
QueryPerformanceCounter(&now);
if ((now.QuadPart - start.QuadPart) * 1000 / freq.QuadPart >= 1000) break;
SwitchToThread();
}
这样能保证两次采样时间差稳定在 ±0.5ms 内,对 Mbps 级别计算足够。
计算速率时必须用 INT64 防止溢出,且要处理字节计数器回绕
网卡驱动内部用 64 位无符号整数累计字节数,但 Windows API 返回的 ifInOctets 是 UINT64。如果只用 DWORD 存上次值,遇到 4GB 回绕(比如 1Gbps 满速跑 34 秒就到 4GB)就会算出负速率。必须全程用 INT64 存前后值,并判断是否发生回绕:
- 若当前值 prev_value,说明发生了回绕,真实增量 = 当前值 + (2^64 − prev_value)
- 但实际中极少见到真回绕(需要连续跑数年),更常见的是驱动未正确初始化计数器,首次读到 0 → 下次读到极大值,此时应丢弃首帧
- 推荐策略:第一次采样后 sleep,第二次再开始计算;或连续三次采样,剔除突变异常值
过滤掉无效适配器:避开隧道、Loopback、Microsoft Kernel Debug Network Adapter
直接遍历所有接口会拿到一堆干扰项:{12345678-ABCD-EF01-2345-678901234567} 这类 GUID 名、WAN Miniport、NDIS Light-Weight Filter,它们不承载真实流量。有效适配器通常满足:
-
IfType是IF_TYPE_ETHERNET_CSMACD(有线)、IF_TYPE_IEEE80211(Wi-Fi)、IF_TYPE_PROPVIRTUAL(Hyper-V 虚拟交换机) -
OperStatus == IF_OPER_STATUS_UP且AdminStatus == IF_ADMIN_STATUS_UP -
Alias或Description字段含 “Ethernet”、“Wi-Fi”、“vEthernet”、“wlan” 等关键词,不含 “Teredo”、“6to4”、“ISATAP”、“Kernel Debug”
别依赖 InterfaceDescription 是否为空来判断有效性——某些 USB 网卡驱动会留空该字段,但流量正常。
真正难的不是获取数字,而是区分哪些数字代表真实业务流量。比如 WSL2 的 vEthernet 适配器,其收发量其实是 Linux 子系统内网通信,和宿主机外网无关;而 DockerNAT 适配器的流出量,可能只是容器访问宿主机 localhost 的 loopback 流量。这些得结合使用场景做语义过滤,没通用解法。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











