直接读取 /proc/net/dev 是获取网卡真实吞吐量与错误包率最轻量可靠的方式;吞吐量基于 rx_bytes 和 tx_bytes 增量计算,错误率基于 rx/tx_packets 与对应 errors 比值,并需处理计数器重置、精确接口匹配及滑动窗口平滑。

直接读取 /proc/net/dev 是 Linux 上获取网卡真实吞吐量与错误包率最轻量、最可靠的方式——它不依赖抓包、不需 root 权限,数据由内核实时维护,更新频率约 100ms,完全反映硬件层收发行为。
提取真实吞吐量:只看 bytes,跳过干扰字段
吞吐量本质是单位时间的字节增量。关键字段只有两个:
- rx_bytes:该网卡自启动以来累计接收字节数(第 2 列,从 0 开始计)
- tx_bytes:该网卡自启动以来累计发送字节数(第 10 列)
注意:/proc/net/dev 前两行是表头和空行,必须跳过;每行以接口名开头(如 eth0:),匹配时要带冒号并做精确前缀比对(避免 eth0 匹配到 eth0:1);字段间可能有多个空格或制表符,用 std::istringstream 配合 >> 自动跳空白更鲁棒。
计算示例(B/s):(current_tx_bytes - last_tx_bytes) / (current_time - last_time).count() * 1e-3(时间差单位毫秒)
计算错误包率:用 packets 和 errors 做比值,不是绝对值
错误包率反映链路质量,应基于包数量而非字节数:
- rx_packets 在第 2 列(紧随 rx_bytes 后),rx_errors 在第 3 列
- tx_packets 在第 10 列,tx_errors 在第 11 列
接收错误率 = rx_errors / (double)rx_packets(若 rx_packets 为 0 则视为 0%)
发送错误率 = tx_errors / (double)tx_packets
注意:errors 是驱动层检测到的硬错误(如 CRC 失败、FIFO 溢出),比用户层丢包更底层、更真实;但单次采样值极小,建议用滑动窗口(如最近 5 秒累计值)平滑计算,避免毛刺。
防坑要点:计数器重置、采样节奏与解析安全
内核统计是累加值,但可能因网卡重载、驱动重初始化而归零。需主动检测:
- 若本次
rx_bytes - 采样间隔建议 200–500ms:太短(如 10ms)常得 0 增量;太长(如 5s)无法捕捉突发流量
- 每次读取都新建
std::ifstream,不复用句柄;逐行用std::getline后先校验是否为空白行(find_first_not_of(" \t") == std::string::npos)
别用 system_clock 计时——NTP 校时会导致时间倒退,速率突变;必须用 std::chrono::steady_clock 打时间戳。
补充诊断:结合 /proc/net/snmp 看 IP 层丢弃线索
/proc/net/dev 只反映驱动层错误,而真实网络问题常发生在上层。可同步读取 /proc/net/snmp 获取 IP 层线索:
- 查找
Icmp:行中的InErrors(ICMP 入错)、OutErrors(ICMP 出错) - 重点关注
InDestUnreachs(目标不可达)和InTimeExcds(TTL 超时)——它们暗示路由路径异常
这些指标不参与吞吐量计算,但当错误包率正常而业务丢包明显时,它们是排查跨网段、防火墙策略、MTU 不匹配的关键依据。

















