c++如何读取Linux下的/proc/net/dev获取网卡流量【实战】

雨枫大大_5257

雨枫大大_5257

2026-04-13

757人浏览

原创

直接读取/proc/net/dev可获取网卡实时流量,需跳过前两行表头,按空格分割提取非空token,取第1个(rx_bytes)和第9个(tx_bytes)字段,校验size≥9后转换为uint64_t,两次采样求差值除以时间间隔得速率。

c++如何读取linux下的/proc/net/dev获取网卡流量【实战】

直接读取 /proc/net/dev 文件就能拿到实时流量数据

Linux 内核通过 /proc/net/dev 暴露每张网卡的收发字节数、包数等统计信息,C++ 只需以文本方式打开并解析该文件即可——它不是设备节点,不需 ioctl 或 socket,也不依赖 libpcap。关键在于格式固定但首两行是表头,且字段对齐靠空格(非制表符),用 std::istringstream 直接按空格切分会因连续空格出错。

  • 文件权限为 world-readable,普通用户可直接 open,无需 root
  • 第 1 行是空行或注释(不同内核版本略有差异),第 2 行是字段名(Inter-|Receive|...),真正数据从第 3 行开始
  • 每行开头是网卡名(如 ens33:),注意末尾带冒号,解析时要 trim 掉
  • 字段共 17 列,其中第 2 列(rx_bytes)和第 10 列(tx_bytes)是核心流量值,单位为字节

用 std::ifstream + 手动跳过表头 + 字符串分割最稳妥

别用 operator>> 直接读整行再 split,因为字段含空格且列宽不一;也别依赖 std::getline 后调 std::stringstream + 多次 >>——它会跳过所有空白(包括中间缺失字段),导致列偏移。正确做法是:逐行读,跳过前两行,对每行先用 find_first_of(' ') 定位网卡名结束位置,再用 substr 提取后续数字部分,最后用 std::stringstream 按空格提取非空 token。

std::ifstream dev("/proc/net/dev");
std::string line;
// 跳过前两行
std::getline(dev, line); // 空行或注释
std::getline(dev, line); // 表头
while (std::getline(dev, line)) {
    auto pos = line.find_first_of(" \t");
    if (pos == std::string::npos) continue;
    std::string iface = line.substr(0, pos);
    if (iface.empty()) continue;
    // 去掉末尾冒号
    if (iface.back() == ':') iface.pop_back();
    // 提取后续字段(跳过开头空白)
    std::string fields = line.substr(pos + 1);
    std::istringstream iss(fields);
    std::vector<:string> tokens;
    std::string tok;
    while (iss >> tok) tokens.push_back(tok);
    // tokens[0] 是 rx_bytes,tokens[8] 是 tx_bytes(索引从 0 开始)
    if (tokens.size() >= 9) {
        uint64_t rx = std::stoull(tokens[0]);
        uint64_t tx = std::stoull(tokens[8]);
        // 使用 rx/tx...
    }
}</:string>

注意字段顺序在不同内核版本中是否一致

从 2.6 到 6.x,/proc/net/dev 的字段顺序基本稳定:第 1 字段是接收字节数(rx_bytes),第 9 字段是发送字节数(tx_bytes)——但这是按空格分割后的第 1 和第 9 个非空 token,不是原始行的第 1 和第 9 列。某些嵌入式发行版或定制内核可能裁剪字段(比如去掉压缩包统计),此时 tokens.size() 可能小于 9。建议加判断,避免 std::stoull 抛 std::out_of_range。

Linux Ai Server
Linux Ai Server

Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。

下载
  • 不要硬编码索引,先检查 tokens.size() >= 9 再取 tokens[0] 和 tokens[8]
  • 若需更高兼容性,可先解析第 2 行表头(如 rx_bytes 出现在第几个位置),但实际中绝大多数场景直接按固定位置更轻量
  • 字段名行(第 2 行)中,rx_bytes 总是在 compressed 左侧、rx_packets 右侧,位置相对固定

两次读取做差值得到瞬时速率要小心时间窗口

仅读一次只能拿到累计值;要算 bps,必须间隔 Δt 秒读两次,再用 (new - old) / Δt。但 Δt 太小(如 100ms)会导致噪声大,Δt 太大(如 5s)则响应滞后。更关键的是:/proc/net/dev 是快照,两次读之间网卡可能 down/up、驱动重置计数器,导致差值为负或异常大。

  • 每次读取后校验:若 new_rx ,说明计数器重置,应丢弃本次差值或打日志告警
  • 建议最小采样间隔 ≥ 1 秒,生产环境常用 2–5 秒
  • 不要用 std::chrono::steady_clock::now() 计算 Δt 后直接除——浮点除法误差在低流量下放大明显,建议统一转成毫秒整数再算 (bytes * 1000) / delta_ms

实际跑起来你会发现,最麻烦的不是读文件,而是处理网卡名里带空格(极少见)、字段缺失、以及某次读取恰好卡在内核更新计数器的瞬间。这些边界情况比语法本身更消耗调试时间。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

linux c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

2023.09.14

13466

6

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1605

5

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

2023.12.21

3677

3

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2024.03.01

5841

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1698

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2604

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6024

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

5529

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

7214

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习