windows平台用getifentry2获取适配器速度最可靠,其speed字段返回真实协商速率(单位bps,如1000000000表示1gbps),需先调用getiftable2获取接口索引再传入,最低支持windows 8;linux则读取/sys/class/net/xxx/speed文件(单位mbps),无线网卡不适用此方式。

Windows平台用GetIfEntry2获取适配器速度
在Windows上,GetIfEntry2 是目前最可靠的方式——它能返回真实协商速率(比如1Gbps、100Mbps),而不是驱动上报的“理论最大值”。注意:必须链接 iphlpapi.lib,且最低支持Windows 8 / Server 2012。
- 先调用
GetIfTable2获取所有接口列表,遍历找InterfaceDescription匹配目标网卡(如"Realtek PCIe GbE Family Controller") - 拿到
NET_IFINDEX后传给GetIfEntry2,其返回结构体中的Speed字段单位是bps(比如1000000000表示1Gbps) - 常见坑:
Speed值为0说明接口未连接或驱动未报告速率;某些虚拟网卡(如Hyper-V交换机、Docker vEthernet)可能始终返回0 - 别用已废弃的
GetIfEntry或GetAdaptersInfo,它们不返回实时协商速率,只返回注册表里硬编码的“MaxSpeed”
Linux下读取/sys/class/net/xxx/speed文件
Linux没有统一API,最稳妥的是直接读取 /sys/class/net/ 下对应接口的 speed 文件——这是内核从物理层实际读出的协商速率,单位是Mbps。
- 路径形如
/sys/class/net/enp0s31f6/speed,需以root权限或确保当前用户有读权限(通常默认可读) - 若文件不存在(如无线网卡、bonding接口、未up的接口),说明该设备不支持或未建立物理链路,此时应 fallback 到
ethtool -s enp0s31f6的输出解析 - 注意:
speed文件内容是纯数字文本(如"1000"),末尾可能带换行符,std::stoi前要trim - 不要依赖
ifconfig或ip link输出——它们不显示协商速率,只显示配置速率或状态
跨平台时避免硬编码接口名
写死 "eth0" 或 "Ethernet" 在多网卡或重命名环境下必然失败。得靠逻辑识别主活动接口。
- 优先选
OperStatus == IF_OPER_STATUS_UP(Windows)或operstate == "up"(Linux)且有IPv4地址的接口 - 排除回环(
lo)、隧道(tun0)、桥接(br0)、docker/veth类虚拟接口(名字含veth、docker、flannel) - 若存在多个候选,按路由表权重选:查
GetIpForwardTable2(Win)或/proc/net/route(Linux),找默认网关所在接口
速度值为0时的真实含义
Speed == 0 不等于“没网”,而是“物理层未协商成功”——常见于网线未插、交换机断电、SFP模块未识别、或驱动不支持速率查询。
- Windows下检查
GetIfEntry2返回值是否为NO_ERROR,再看Speed;若返回ERROR_NOT_FOUND或ERROR_INVALID_PARAMETER,说明接口索引无效 - Linux下
cat /sys/class/net/eth0/speed报No such device或返回空,需确认ethtool eth0中Speed:行是否正常 - 无线网卡永远不走
speed文件——它用/proc/net/wireless或iw dev wlan0 link查tx bitrate,但那只是当前传输速率,非链路协商速率
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











