Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Chinese
  4. QModbusTcpClient 内存泄漏
Qt 6.11 is out! See what's new in the release blog

QModbusTcpClient 内存泄漏

Scheduled Pinned Locked Moved Unsolved Chinese
2 Posts 2 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • neemeN Offline
    neemeN Offline
    neeme
    wrote on last edited by
    #1

    大家好:

    我在使用 QModbusTcpClient 用以太网 modbus tcp 读数据时能正常。但发现不停增加内存使用。
    只要有数据接收到就会几K内存增加。半天不到程序使用内存120M+ 了。启动时是8M。
    而我用QModbusRtuSerialMaster 用RS485 一切很正常,内存不会增加!

    #ifndef CMODBUS_H
    #define CMODBUS_H
    
    #include <QModbusTcpClient>
    #include <CSerialPortConfig.h>
    #include <QModbusRtuSerialMaster>
    
    class CModBus : public CSerialPortConfig
    {
        Q_OBJECT
    public:
        explicit CModBus(const QString &capstr);
        ~CModBus();
    
        void portOpen();
        void portClose();
        bool portIsOpen();
    
        void read(const QModbusDataUnit &mdu, const int &address);
        void write(const QModbusDataUnit &mdu, const int &address);
    
    signals:
        void linkState(const int &address, const bool &st);
        void dataReady(const int &address, const QModbusDataUnit &mdu);
    
    private:
        void readReady();
        void writeFinished();
        void newSetttings(const Settings &ns);
        void errorOccurred(const QModbusDevice::Error &error);
    
        int m_lastAddress = 0;
        QModbusClient *m_device = nullptr;
    };
    
    #endif // CMODBUS_H
    
    
    #include "CModBus.h"
    
    CModBus::CModBus(const QString &capstr) : CSerialPortConfig(capstr)
    {    
        newSetttings(curSettings());
        connect(this, &CSerialPortConfig::sigNewSetttings, this, &CModBus::newSetttings);
        connect(m_device, &QModbusClient::errorOccurred, this, &CModBus::errorOccurred);
        m_device->connectDevice();
    
        if(m_device->state() != QModbusDevice::ConnectedState)
        {
            errorAppend(capstr + " : " + portName() + tr(" : port error!"));
        }
    }
    
    CModBus::~CModBus()
    {
    
    }
    
    void CModBus::newSetttings(const Settings &ns)
    {
        bool isopen = false;
    
        if(m_device != nullptr)
        {
            isopen = (m_device->state() == QModbusDevice::ConnectedState);
            delete m_device;
            m_device = nullptr;
        }
    
        if(ns.tcpEnable)
        {
            m_device = new QModbusTcpClient(this);
            const QUrl url = QUrl::fromUserInput(ns.tcpHost);
            m_device->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());
            m_device->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());
        }
        else
        {
            m_device = new QModbusRtuSerialMaster(this);
            m_device->setConnectionParameter(QModbusDevice::SerialPortNameParameter, ns.portName);
            m_device->setConnectionParameter(QModbusDevice::SerialParityParameter, ns.parity);
            m_device->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, ns.baud);
            m_device->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, ns.dataBits);
            m_device->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, ns.stopBits);
        }
    
        m_device->setTimeout(ns.responseTime);
        m_device->setNumberOfRetries(ns.numberOfRetries);
    
        if(isopen)
        {
            m_device->connectDevice();
        }
    
    }
    
    void CModBus::read(const QModbusDataUnit &mdu, const int &address)
    {
        if((!m_device) || (m_device->state() != QModbusDevice::ConnectedState))
        {
            emit linkState(address, false);
            return;
        }
    
        QModbusReply *reply = m_device->sendReadRequest(mdu, address);
    
        if(reply)
        {
            m_lastAddress = address;
    
            if(!reply->isFinished())
            {
                connect(reply, &QModbusReply::finished, this, &CModBus::readReady);
            }
            else
            {
                emit linkState(address, false);
                delete reply;
            }
        }
        else
        {
            emit linkState(address, false);
        }
    }
    
    void CModBus::write(const QModbusDataUnit &mdu, const int &address)
    {
        if((!m_device) || (m_device->state() != QModbusDevice::ConnectedState))
        {
            emit linkState(address, false);
            return;
        }
    
        QModbusReply *reply = m_device->sendWriteRequest(mdu, address);
    
        if(reply)
        {
            m_lastAddress = address;
    
            if(!reply->isFinished())
            {
                connect(reply, &QModbusReply::finished, this, &CModBus::writeFinished);
            }
            else
            {
                emit linkState(address, false);
                delete reply;
            }
        }
        else
        {
            emit linkState(address, false);
        }
    }
    
    void CModBus::readReady()
    {
        QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
    
        if(!reply)
        {
            emit linkState(m_lastAddress, false);
            return;
        }
    
        const int address = reply->serverAddress();
        const QModbusDataUnit mdu = reply->result();
    
        if(reply->error() == QModbusDevice::NoError)
        {
            emit dataReady(address, mdu);
            emit linkState(address, true);
        }
        else
        {
            emit linkState(m_lastAddress, false);
        }
    
        reply->deleteLater();
    }
    
    void CModBus::writeFinished()
    {
        auto *reply = qobject_cast<QModbusReply *>(sender());
    
        if(!reply)
        {
            emit linkState(m_lastAddress, false);
            return;
        }
    
        if(reply->error() == QModbusDevice::NoError)
        {
            emit linkState(reply->serverAddress(), true);
        }
        else
        {
            emit linkState(m_lastAddress, false);
        }
    
        reply->deleteLater();
    }
    
    void CModBus::errorOccurred(const QModbusDevice::Error &error)
    {
        Q_UNUSED(error)
        emit linkState(m_lastAddress, false);
    }
    
    void CModBus::portOpen()
    {
        m_device->connectDevice();
    }
    
    void CModBus::portClose()
    {
        m_device->disconnectDevice();
    }
    
    bool CModBus::portIsOpen()
    {
        return (m_device->state() == QModbusDevice::ConnectedState);
    }
    
    
    
    
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      bigWave
      wrote on last edited by
      #2

      sendWriteRequest(mdu, address);会自动创建个新的qmodbusreply 的对象,我怀疑这个对象没有释放导致的,但是试了很多方法都不行,不知道楼主是怎么解决的??

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved