You need to enable JavaScript to run this app. QT开发Modbus TCP服务器如何实现QModbusTcpConnectionObserver解决虚类实例化问题
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 07:15:11