QModbusTcpClient 内存泄漏

neeme 2021-04-18 10:01:33
大家好:

我在使用 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);
}




...全文
1041 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45835939 2022-11-24
  • 打赏
  • 举报
回复

请问楼主解决了嘛?求问

SERB666 2022-09-08
  • 打赏
  • 举报
回复

我遇到了同样的问题,QModbusTCP 的reply是否根本没有被释放内存? 通讯越久,内存越大! 有人一起交流吗?

weixin_45835939 2022-11-24
  • 举报
回复
@SERB666 兄弟 后来解决了嘛?
SERB666 2022-11-24
  • 举报
回复
@weixin_45835939 没有,无法解决
weixin_45835939 2023-05-02
  • 举报
回复 1
@SERB666 我后来使用Qt5.15.2,保证服务器(无论读写)有响应,同时添加m_pClient-&gt;disconnect(SIGNAL(timeoutChanged(int)),0,0);就没有内存泄漏了。
1条回复
qiuyueyuan 2022-03-24
  • 打赏
  • 举报
回复

我也遇到了这个问题。就直接跑他的master 例子。走TCP模式链接。内存也会不断地增长。不知道兄弟怎么解决的。
我是50ms去读7个寄存器值,当然QModbusReply肯定是删掉的。整个程序的内存增长不是太明显,差不多1个小时10MB
我从晚上11点开启程序跑,此时程序为7MB不到。到早上6点。整个程序是70MB。
不知道楼主怎么解决这个问题

SERB666 2022-11-24
  • 举报
回复
@qiuyueyuan 和你一样的,其他的例如QModbus Rtu就没问题
大浪太深 2022-02-23
  • 打赏
  • 举报
回复

我用232也遇到这个问题,无奈

鹏? 2022-03-16
  • 举报
回复
@大浪太深 当时有哪行写错了反正,忘了怎么改的了
鹏? 2021-11-04
  • 打赏
  • 举报
回复

同样遇到此问题,楼主怎么解决的?

源代码大师 2021-05-08
  • 打赏
  • 举报
回复
希望对你有帮助:https://blog.csdn.net/it_xiangqiang/category_10794527.html

16,203

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧