QModbusTcpClient 内存泄漏
Unsolved
Chinese
-
大家好:
我在使用 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); }