QT开发Modbus TCP服务器如何实现QModbusTcpConnectionObserver解决虚类实例化问题
QT Modbus TCP 服务器ConnectionObserver实现指南
对应问题场景
基于QT开发Modbus TCP服务器时,需要通过ConnectionObserver实现客户端连接的精细化管控,但官方文档中installConnectionObserver()接口要求传入QModbusTcpConnectionObserver*类型指针,而该类为抽象虚类,无法直接创建实例,需要可落地的实现方案。
实现逻辑
QModbusTcpConnectionObserver是仅定义接入拦截接口规范的抽象基类,不存在可直接实例化的对象。只要通过公有继承该类、完整实现类中所有纯虚方法,生成可实例化的自定义子类,就可以满足接口传参要求,同时可在子类中嵌入任意自定义的连接管控逻辑。
具体实现步骤
- 第一步:编写自定义观察者子类
重写抽象类中唯一的纯虚方法newConnection(QTcpSocket *socket),方法的返回值将直接决定是否允许当前客户端接入。你可以在这个方法里写任意连接校验逻辑,示例代码如下:#include <QModbusTcpConnectionObserver> #include <QTcpSocket> #include <QDebug> class CustomModbusConnObserver : public QModbusTcpConnectionObserver { public: bool newConnection(QTcpSocket *socket) override { // 示例:IP白名单校验 QHostAddress peerAddr = socket->peerAddress(); if (!ipWhiteList.contains(peerAddr.toString())) { qDebug() << "拦截非授权IP连接:" << peerAddr; socket->disconnectFromHost(); return false; } // 示例:维护当前有效连接列表,绑定断开信号做状态同步 activeConnList.append(socket); connect(socket, &QTcpSocket::disconnected, this, [this, socket]() { activeConnList.removeAll(socket); qDebug() << "客户端正常断开:" << socket->peerAddress(); socket->deleteLater(); }); return true; } // 自定义业务属性 QStringList ipWhiteList; QList<QTcpSocket*> activeConnList; }; - 第二步:将观察者实例挂载到Modbus服务器
由于接口不会接管传入观察者的内存所有权,需要保证观察者对象的生命周期长于Modbus服务器实例,避免悬垂指针问题。示例代码如下:// 初始化Modbus TCP服务器 QModbusTcpServer *tcpModbusServer = new QModbusTcpServer(this); // 创建自定义观察者实例,可设置为类成员变量,或通过QObject父子机制管理内存 CustomModbusConnObserver *connObserver = new CustomModbusConnObserver(); connObserver->ipWhiteList << "127.0.0.1" << "192.168.1.100"; // 安装连接观察者 tcpModbusServer->installConnectionObserver(connObserver); // 启动服务监听 if (!tcpModbusServer->listen(QHostAddress::Any, 502)) { qDebug() << "服务启动失败:" << tcpModbusServer->errorString(); }
注意事项
- 纯虚方法必须完整实现:如果自定义子类没有完全重写
newConnection方法,该类依然是抽象类型,无法正常实例化。注意方法返回值的语义:返回true则服务器正常接收该客户端连接,返回false则服务器会主动断开该连接,是实现接入管控的核心入口。 - 禁止向
installConnectionObserver传入栈上的临时局部对象:接口不会对传入的对象做内存回收,如果使用临时栈对象,函数退出后对象销毁,会引发服务器内部的悬垂指针访问。建议将观察者作为服务器类的成员变量,或设置和服务器相同的QObject父对象统一管理生命周期。 - 在
newConnection方法中可以扩展任意精细化管控能力,包括最大连接数限制、客户端身份校验、连接流量统计、连接状态实时推送等。
内容的提问来源于stack exchange,提问作者niko95
相关产品推荐
相关产品推荐

