From af7ae6b334a57dfb28076ecc2dc22ac12bfa9887 Mon Sep 17 00:00:00 2001 From: Jokul Date: Thu, 23 Jul 2026 00:06:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=A1=E6=95=B0=E5=99=A8=E5=9B=9E?= =?UTF-8?q?=E7=BB=95/=E9=87=8D=E7=BD=AE=E6=97=B6=E9=92=B3=E5=88=B6?= =?UTF-8?q?=E8=B4=9F=E9=80=9F=E5=BA=A6=E4=B8=BA0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 网卡重启、/proc/net/dev 计数器溢出或接口重置时,字节差值为负, QML 会显示负速度。对 rxDelta/txDelta 钳制为 0 避免此问题。 --- docs/project-review.md | 5 +++-- src/networkmonitorapplet.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/project-review.md b/docs/project-review.md index dc67d6c..cf77ffb 100644 --- a/docs/project-review.md +++ b/docs/project-review.md @@ -13,8 +13,9 @@ ~~`calculateSpeed()` 直接用 `currentRxBytes - m_lastRxBytes` 作为 bytes/sec,未除以实际流逝时间。系统负载高或定时器抖动时,速度值会失真。~~ 已改为记录上次采样的毫秒时间戳 `m_lastTimestampMs`,按真实流逝时间 `delta_bytes / elapsed_seconds` 计算速度;速度存储由 `qint64` 改为 `double` 保留精度;`elapsedSec > 0` 守卫避免除零。 -**2. 计数器回绕/重置产生负速度** -网卡重启、`/proc/net/dev` 计数器溢出或接口重置时,`currentRxBytes - m_lastRxBytes` 可能为负。代码无任何兜底,QML 会显示负速度。应加 `if (delta < 0) delta = 0;` 保护。 +**2. ~~计数器回绕/重置产生负速度~~ ✅ 已修复** +~~网卡重启、`/proc/net/dev` 计数器溢出或接口重置时,`currentRxBytes - m_lastRxBytes` 可能为负。代码无任何兜底,QML 会显示负速度。~~ +已在 `calculateSpeed()` 中对 `rxDelta` / `txDelta` 钳制为 0,计数器回绕/接口重置/网卡重启时不再产生负速度。 **3. "总量统计"语义有误导** `m_totalDownload = currentRxBytes` 只存储活动接口的当前计数器值,并非真正的累计流量。它会在以下场景跳变:切换网卡(跳到新接口计数器)、网卡重启(归零)、系统重启(归零)。README 宣称"累计上传/下载流量统计",但实际不是跨重启/跨接口的累计。 diff --git a/src/networkmonitorapplet.cpp b/src/networkmonitorapplet.cpp index fb12b05..7c104fd 100644 --- a/src/networkmonitorapplet.cpp +++ b/src/networkmonitorapplet.cpp @@ -378,8 +378,12 @@ void NetworkMonitorApplet::calculateSpeed() // 仅当间隔合法时计算速度,避免除零;间隔为 0 时保持上次速度值 if (elapsedSec > 0) { - m_downloadSpeed = (currentRxBytes - m_lastRxBytes) / elapsedSec; - m_uploadSpeed = (currentTxBytes - m_lastTxBytes) / elapsedSec; + // 计数器回绕/接口重置时差值可能为负,钳制为 0 避免显示负速度 + // 触发场景:网卡重启、/proc/net/dev 计数器溢出、USB 网卡拔出重插 + const qint64 rxDelta = currentRxBytes - m_lastRxBytes; + const qint64 txDelta = currentTxBytes - m_lastTxBytes; + m_downloadSpeed = (rxDelta > 0 ? rxDelta : 0) / elapsedSec; + m_uploadSpeed = (txDelta > 0 ? txDelta : 0) / elapsedSec; } m_lastRxBytes = currentRxBytes;