做 Qt 上位机,网络通信经常会遇到一个看起来很简单、实际非常麻烦的问题:
网线插着,就代表网络可用吗?
当然不是。工业现场可能出现:
-
网线被拔掉
-
Wi-Fi 断开
-
网卡被禁用
-
IP 地址发生变化
-
DHCP 重新分配地址
-
路由器异常
-
局域网正常,但服务器连接不上
-
网络恢复以后,原来的 TCP 连接已经失效
如果程序只是启动时判断一次网络状态,运行几个小时以后基本就不可靠了。
Qt 5 中,QNetworkConfigurationManager 曾经是网络配置和 Bearer 状态管理的重要 API;而在 Qt 6 中,这套 Bearer Management 已经移除,官方提供了新的 QNetworkInformation。
所以今天这篇文章,我们把两套方案一起讲清楚。
一、先搞清楚:网络状态到底是什么?
很多程序喜欢写:
cpp
if (networkAvailable) {
sendData();
}
问题是:networkAvailable 到底代表什么?
至少可以拆成四层:

例如:

每一层都正常,才是真正意义上的"业务网络可用"。
所以网络状态监控不能简单理解成:
"有没有网卡?"
而应该理解成:
当前网络连接处于什么状态,以及我的业务是否还能正常通信。
二、Qt 5:QNetworkConfigurationManager
在 Qt 5 中:
#include <QNetworkConfigurationManager>
核心对象就是:
QNetworkConfigurationManager manager;
它可以用来查询当前系统中的网络配置,并监听配置变化。
常见 API 包括:
-
allConfigurations()返回所有符合指定状态标志的网络配置。状态标志可以是如"已启用"(Active)、"可用"(Discovered)等。 -
defaultConfiguration()返回当前的默认网络配置。默认配置通常是系统当前使用的网络配置。 -
configurationFromIdentifier() -
capabilities()
同时还有几个非常重要的信号:
-
configurationAdded() -
configurationRemoved()当某个网络配置被移除时发出此信号。可以用来处理配置被删除的情况。 -
configurationChanged()当某个网络配置发生变化时发出此信号。这个信号可以用于监控某个特定的网络配置。 -
**void onlineStateChanged(bool isOnline)**当系统的在线状态发生变化时发出此信号。如果系统从离线切换到在线,或反之,会发出该信号。
例如:
cpp
QNetworkConfigurationManager *manager =
new QNetworkConfigurationManager(this);
connect(manager,
&QNetworkConfigurationManager::configurationChanged,
this,
[]() {
qDebug() << "Network configuration changed";
});
这样,当系统网络配置发生变化时,程序就可以得到通知。
三、不要把"配置变化"当成"网络断开"
这是使用 QNetworkConfigurationManager 时最容易犯的错误。
例如:

这个信号表达的是:
网络配置发生了变化。
它并不严格等价于:
服务器已经连接不上了。
同样,configurationChanged() 也不代表 TCP 连接一定断开,更不能直接写成:
cpp
connect(manager,
&QNetworkConfigurationManager::configurationChanged,
this,
&NetworkManager::disconnectFromServer);
这种设计非常危险。
更合理的结构应该是:

网络配置只是输入条件之一。
四、Qt 5 中一个典型的监控器
可以把网络状态统一封装成一个类:
cpp
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;
};
初始化:
cpp
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 程序建议设计两层监控:

例如定义:
cpp
enum class NetworkState
{
Unknown,
Offline,
Connecting,
Online,
Degraded
};
这样比一个 bool networkAvailable; 强很多。
七、Qt 6:QNetworkInformation
如果项目使用 Qt 6,就不要再围绕 QNetworkConfigurationManager 设计新代码。
Qt 6 提供:
#include <QNetworkInformation>
官方 API 从 Qt 6.1 开始提供网络相关信息。它支持网络可达性、传输介质、计费网络、Captive Portal 等能力。
最核心的是 QNetworkInformation::Reachability,包括:
-
Unknown -
Disconnected -
Local -
Site -
Online
也就是说,Qt 6 对网络状态的表达更加接近:
Disconnected → Local → Site → Online
而不是简单的 true / false。
八、Qt 6 网络状态监控实战
首先加载默认 Backend:
QNetworkInformation::loadDefaultBackend();
然后获取实例:
auto *info = QNetworkInformation::instance();
读取当前状态:
cpp
auto state = info->reachability();
if (state ==
QNetworkInformation::Reachability::Online) {
qDebug() << "Network online";
}
更重要的是监听:
cpp
connect(info,
&QNetworkInformation::reachabilityChanged,
this,
[](QNetworkInformation::Reachability state) {
qDebug() << "Reachability changed:"
<< static_cast<int>(state);
});
这样网络发生变化时,应用可以及时响应。
九、Qt 6 还能判断当前网络介质
从 Qt 6.3 开始,还可以获取 transportMedium():
auto medium = info->transportMedium();
可能得到:
-
Ethernet -
WiFi -
Cellular -
Bluetooth -
Unknown
于是工业软件可以进一步区分:
Ethernet → 工业设备通信 Wi-Fi → 普通业务通信 Cellular → 远程维护 / 云端通信
官方文档也说明,当用户拔掉网线、离开 Wi-Fi 范围或开启飞行模式时,传输介质发生变化会触发对应信号。
十、网络监控不要直接控制业务
一个常见的错误架构:

这样很容易产生大量状态竞争。
更推荐:
cpp
NetworkMonitor
│
▼
NetworkState
│
▼
ConnectionManager
│
┌────────────┼────────────┐
▼ ▼ ▼
TCP HTTP MQTT
│ │ │
└────────────┼────────────┘
▼
BusinessService
也就是说:
-
NetworkMonitor负责"观察" -
ConnectionManager负责"连接" -
职责不要混在一起
十一、工业项目推荐:状态机管理网络连接
如果是 7×24 小时运行的 Qt 上位机,可以进一步设计状态机:
cpp
┌─────────────┐
│ Init │
└──────┬──────┘
▼
┌─────────────┐
│ Disconnected│
└──────┬──────┘
│ network available
▼
┌─────────────┐
│ Connecting │
└──────┬──────┘
│ success
▼
┌─────────────┐
│ Online │
└──────┬──────┘
│ error
▼
┌─────────────┐
│ Reconnecting│
└──────┬──────┘
│
└──────────► Connecting
再增加业务探活:
cpp
Online
│
│ heartbeat timeout
▼
Degraded
│
│ recover
▼
Online
这样网络系统就不再是简单的 if (connected),而是一个真正的连接生命周期。
十二、心跳比"判断网络在线"更可靠
例如 TCP 长连接,使用 QTimer *heartbeatTimer; 周期性发送:
cpp
Heartbeat → Server → Heartbeat ACK
如果发送成功 + 收到 ACK,才能认为业务连接正常。
如果连续三次没有响应:
bash
Heartbeat
Heartbeat
Heartbeat
↓
Timeout
↓
Disconnected
↓
Reconnect
这比单纯判断 QNetworkInformation::Reachability::Online 更加接近真实业务状态。
Qt 官方也特别提醒,QNetworkInformation::reachability() 是基于操作系统 / Backend 的判断,在某些情况下可能并不准确,因此不应该把它作为连接服务器前的绝对"预检查"。
十三、最终推荐的 Qt 上位机架构
如果是工业通信软件,我更推荐把网络模块设计成:
cpp
MainWindow
│
▼
Application Layer
│
▼
NetworkManager
│
┌──────────────┼──────────────┐
▼ ▼ ▼
NetworkMonitor ConnectionMgr Heartbeat
│ │ │
▼ ▼ ▼
QNetworkInformation TCP/HTTP Timer
/ Qt5 QNCM
│ │ │
└──────────────┼──────────────┘
▼
NetworkState
│
┌──────────┼──────────┐
▼ ▼ ▼
Online Degraded Offline
│
▼
BusinessService
│
┌─────┴─────┐
▼ ▼
PLC Server
这里有一个非常重要的设计思想:
网络状态监控是基础设施,不应该直接侵入业务代码。
业务层只关心:
-
Online -
Offline -
Degraded
而不需要到处写 QNetworkConfigurationManager 或者 QNetworkInformation。
十四、Qt 5 和 Qt 6 到底怎么选?
可以简单对比:
| 项目 | Qt 5 | Qt 6 |
|---|---|---|
| 网络配置 | QNetworkConfigurationManager |
QNetworkInformation |
| Bearer Management | 有 | 已移除 |
| 网络可达性 | 间接判断 | Reachability |
| Wi-Fi / Ethernet | QNetworkConfiguration |
TransportMedium |
| 新项目 | 不建议继续依赖 | 推荐 |
| 老项目 | 可以继续维护 | 建议逐步迁移 |
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 中的网络信息接口。