资讯动态

QNetworkConfigurationManager 与网络状态监控:Qt 上位机如何判断网络真的可用

发布时间:2026/10/14 3:30:32 来源:尧图企业网站定制
做 Qt 上位机网络通信经常会遇到一个看起来很简单、实际非常麻烦的问题网线插着就代表网络可用吗当然不是。工业现场可能出现网线被拔掉Wi-Fi 断开网卡被禁用IP 地址发生变化DHCP 重新分配地址路由器异常局域网正常但服务器连接不上网络恢复以后原来的 TCP 连接已经失效如果程序只是启动时判断一次网络状态运行几个小时以后基本就不可靠了。Qt 5 中QNetworkConfigurationManager曾经是网络配置和 Bearer 状态管理的重要 API而在 Qt 6 中这套 Bearer Management 已经移除官方提供了新的QNetworkInformation。所以今天这篇文章我们把两套方案一起讲清楚。一、先搞清楚网络状态到底是什么很多程序喜欢写if (networkAvailable) { sendData(); }问题是networkAvailable到底代表什么至少可以拆成四层例如每一层都正常才是真正意义上的“业务网络可用”。所以网络状态监控不能简单理解成“有没有网卡”而应该理解成当前网络连接处于什么状态以及我的业务是否还能正常通信。二、Qt 5QNetworkConfigurationManager在 Qt 5 中#include QNetworkConfigurationManager核心对象就是QNetworkConfigurationManager manager;它可以用来查询当前系统中的网络配置并监听配置变化。常见 API 包括allConfigurations()返回所有符合指定状态标志的网络配置。状态标志可以是如“已启用”Active、“可用”Discovered等。defaultConfiguration()返回当前的默认网络配置。默认配置通常是系统当前使用的网络配置。configurationFromIdentifier()capabilities()同时还有几个非常重要的信号configurationAdded()configurationRemoved()当某个网络配置被移除时发出此信号。可以用来处理配置被删除的情况。configurationChanged()当某个网络配置发生变化时发出此信号。这个信号可以用于监控某个特定的网络配置。void onlineStateChanged(bool isOnline)当系统的在线状态发生变化时发出此信号。如果系统从离线切换到在线或反之会发出该信号。例如QNetworkConfigurationManager *manager new QNetworkConfigurationManager(this); connect(manager, QNetworkConfigurationManager::configurationChanged, this, []() { qDebug() Network configuration changed; });这样当系统网络配置发生变化时程序就可以得到通知。三、不要把“配置变化”当成“网络断开”这是使用QNetworkConfigurationManager时最容易犯的错误。例如这个信号表达的是网络配置发生了变化。它并不严格等价于服务器已经连接不上了。同样configurationChanged()也不代表 TCP 连接一定断开更不能直接写成connect(manager, QNetworkConfigurationManager::configurationChanged, this, NetworkManager::disconnectFromServer);这种设计非常危险。更合理的结构应该是网络配置只是输入条件之一。四、Qt 5 中一个典型的监控器可以把网络状态统一封装成一个类class NetworkMonitor : public QObject { Q_OBJECT public: explicit NetworkMonitor(QObject *parent nullptr); signals: void networkChanged(bool available); private slots: void onConfigurationChanged( const QNetworkConfiguration config); private: QNetworkConfigurationManager *m_manager; };初始化NetworkMonitor::NetworkMonitor(QObject *parent) : QObject(parent) { m_manager new QNetworkConfigurationManager(this); connect(m_manager, QNetworkConfigurationManager::configurationChanged, this, NetworkMonitor::onConfigurationChanged); }然后根据当前配置重新判断状态。不过这里有一个关键问题不要只依赖系统状态。五、为什么“网络已连接”仍然可能访问不了服务器举一个工业现场非常典型的场景此时网卡正常IP正常网关正常局域网正常但是Server:192.168.1.100:8080已经挂掉了。此时操作系统可能仍然认为网络在线但你的业务实际上已经无法通信。所以系统网络状态 ≠ 业务网络状态。这是网络监控设计中最重要的一条原则。六、正确做法系统状态 业务探活工业 Qt 程序建议设计两层监控例如定义enum class NetworkState { Unknown, Offline, Connecting, Online, Degraded };这样比一个bool networkAvailable;强很多。七、Qt 6QNetworkInformation如果项目使用 Qt 6就不要再围绕QNetworkConfigurationManager设计新代码。Qt 6 提供#include QNetworkInformation官方 API 从 Qt 6.1 开始提供网络相关信息。它支持网络可达性、传输介质、计费网络、Captive Portal 等能力。最核心的是QNetworkInformation::Reachability包括UnknownDisconnectedLocalSiteOnline也就是说Qt 6 对网络状态的表达更加接近Disconnected → Local → Site → Online而不是简单的true / false。八、Qt 6 网络状态监控实战首先加载默认 BackendQNetworkInformation::loadDefaultBackend();然后获取实例auto *info QNetworkInformation::instance();读取当前状态​​​​​​​auto state info-reachability(); if (state QNetworkInformation::Reachability::Online) { qDebug() Network online; }更重要的是监听​​​​​​​connect(info, QNetworkInformation::reachabilityChanged, this, [](QNetworkInformation::Reachability state) { qDebug() Reachability changed: static_castint(state); });这样网络发生变化时应用可以及时响应。九、Qt 6 还能判断当前网络介质从 Qt 6.3 开始还可以获取transportMedium()auto medium info-transportMedium();可能得到EthernetWiFiCellularBluetoothUnknown于是工业软件可以进一步区分​​​​​​​Ethernet → 工业设备通信 Wi-Fi → 普通业务通信 ​​​​​​​​​​​​​​Cellular → 远程维护 / 云端通信官方文档也说明当用户拔掉网线、离开 Wi-Fi 范围或开启飞行模式时传输介质发生变化会触发对应信号。十、网络监控不要直接控制业务一个常见的错误架构这样很容易产生大量状态竞争。更推荐​​​​​​​NetworkMonitor │ ▼ NetworkState │ ▼ ConnectionManager │ ┌────────────┼────────────┐ ▼ ▼ ▼ TCP HTTP MQTT │ │ │ └────────────┼────────────┘ ▼ BusinessService也就是说NetworkMonitor负责“观察”ConnectionManager负责“连接”职责不要混在一起十一、工业项目推荐状态机管理网络连接如果是 7×24 小时运行的 Qt 上位机可以进一步设计状态机​​​​​​​┌─────────────┐ │ Init │ └──────┬──────┘ ▼ ┌─────────────┐ │ Disconnected│ └──────┬──────┘ │ network available ▼ ┌─────────────┐ │ Connecting │ └──────┬──────┘ │ success ▼ ┌─────────────┐ │ Online │ └──────┬──────┘ │ error ▼ ┌─────────────┐ │ Reconnecting│ └──────┬──────┘ │ └──────────► Connecting再增加业务探活​​​​​​​Online │ │ heartbeat timeout ▼ Degraded │ │ recover ▼ Online这样网络系统就不再是简单的if (connected)而是一个真正的连接生命周期。十二、心跳比“判断网络在线”更可靠例如 TCP 长连接使用QTimer *heartbeatTimer;周期性发送Heartbeat → Server → Heartbeat ACK如果发送成功 收到 ACK才能认为业务连接正常。如果连续三次没有响应​​​​​​​Heartbeat Heartbeat Heartbeat ↓ Timeout ↓ Disconnected ↓ Reconnect这比单纯判断QNetworkInformation::Reachability::Online更加接近真实业务状态。Qt 官方也特别提醒QNetworkInformation::reachability()是基于操作系统 / Backend 的判断在某些情况下可能并不准确因此不应该把它作为连接服务器前的绝对“预检查”。十三、最终推荐的 Qt 上位机架构如果是工业通信软件我更推荐把网络模块设计成​​​​​​​MainWindow │ ▼ Application Layer │ ▼ NetworkManager │ ┌──────────────┼──────────────┐ ▼ ▼ ▼ NetworkMonitor ConnectionMgr Heartbeat │ │ │ ▼ ▼ ▼ QNetworkInformation TCP/HTTP Timer / Qt5 QNCM │ │ │ └──────────────┼──────────────┘ ▼ NetworkState │ ┌──────────┼──────────┐ ▼ ▼ ▼ Online Degraded Offline │ ▼ BusinessService │ ┌─────┴─────┐ ▼ ▼ PLC Server这里有一个非常重要的设计思想网络状态监控是基础设施不应该直接侵入业务代码。业务层只关心OnlineOfflineDegraded而不需要到处写QNetworkConfigurationManager或者QNetworkInformation。十四、Qt 5 和 Qt 6 到底怎么选可以简单对比项目Qt 5Qt 6网络配置QNetworkConfigurationManagerQNetworkInformationBearer Management有已移除网络可达性间接判断ReachabilityWi-Fi / EthernetQNetworkConfigurationTransportMedium新项目不建议继续依赖推荐老项目可以继续维护建议逐步迁移Qt 6 官方已经移除了QNetworkConfigurationManager体系因此如果现在开始设计新的 Qt 6 工业项目建议直接以QNetworkInformation QNetworkInterface QTcpSocket/QNetworkAccessManager为基础。十五、最后总结QNetworkConfigurationManager解决的是 Qt 5 时代的网络配置与 Bearer 状态管理问题。但真正可靠的网络监控不能只看一个 API。应该分成三层​​​​​​​第一层系统网络 ──► 网卡 / IP / Wi-Fi / Ethernet↓第二层网络可达性 ──► Local / Site / Online↓第三层业务连接 ──► TCP / HTTP / 心跳 / ACK最终得到​​​​​​​系统在线 业务可达 心跳正常 ⇒ 真正 Online系统在线 服务器连接失败 ⇒ Degraded而不是简单地认为“系统在线 业务在线”。这也是 Qt 工业上位机网络模块从“能用”走向“稳定”的一个关键变化。对于新项目优先考虑 Qt 6 的QNetworkInformation对于 Qt 5 老项目QNetworkConfigurationManager仍然可以作为现有代码的网络配置监控手段但最好把它封装在NetworkMonitor后面为后续迁移到 Qt 6 留出接口。Qt 6.8 官方文档目前也将QNetworkInformation作为 Qt Network 中的网络信息接口。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑