qt modbus tcp缓存区的示例不使用modbus库
时间: 2023-09-23 10:10:06 浏览: 80
Qt使用ModbusTcp与汇川PLC通讯
以下是一个使用Qt的示例代码,演示如何使用TCP套接字来实现Modbus TCP通信,并且不依赖于任何第三方Modbus库。
```cpp
#include <QtNetwork>
// Modbus TCP 报文头
struct ModbusTcpHeader {
quint16 transactionId;
quint16 protocolId;
quint16 length;
quint8 unitId;
};
// Modbus TCP 请求报文体
struct ModbusTcpRequest {
quint16 functionCode;
quint16 startAddress;
quint16 count;
};
// Modbus TCP 响应报文体
struct ModbusTcpResponse {
quint8 byteCount;
QByteArray data;
};
class ModbusTcpClient : public QObject
{
Q_OBJECT
public:
explicit ModbusTcpClient(QObject *parent = nullptr);
void connectToServer(const QString &host, quint16 port);
bool readHoldingRegisters(quint8 unitId, quint16 startAddress, quint16 count, QVector<quint16> &values);
private slots:
void onConnected();
void onDisconnected();
void onError(QAbstractSocket::SocketError error);
void onReadyRead();
private:
void sendRequest(const QByteArray &data);
bool parseResponse(const QByteArray &data, QVector<quint16> &values);
private:
QTcpSocket *m_socket;
quint16 m_transactionId;
};
ModbusTcpClient::ModbusTcpClient(QObject *parent) : QObject(parent),
m_socket(new QTcpSocket(this)),
m_transactionId(0)
{
connect(m_socket, &QTcpSocket::connected, this, &ModbusTcpClient::onConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &ModbusTcpClient::onDisconnected);
connect(m_socket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), this, &ModbusTcpClient::onError);
connect(m_socket, &QTcpSocket::readyRead, this, &ModbusTcpClient::onReadyRead);
}
void ModbusTcpClient::connectToServer(const QString &host, quint16 port)
{
m_socket->connectToHost(host, port);
}
bool ModbusTcpClient::readHoldingRegisters(quint8 unitId, quint16 startAddress, quint16 count, QVector<quint16> &values)
{
ModbusTcpHeader header;
header.transactionId = ++m_transactionId;
header.protocolId = 0;
header.length = 6;
header.unitId = unitId;
ModbusTcpRequest request;
request.functionCode = 3;
request.startAddress = startAddress;
request.count = count;
QByteArray requestData;
requestData.append(reinterpret_cast<const char *>(&header), sizeof(header));
requestData.append(reinterpret_cast<const char *>(&request), sizeof(request));
sendRequest(requestData);
values.clear();
if (m_socket->waitForReadyRead()) {
QByteArray responseData = m_socket->readAll();
return parseResponse(responseData, values);
} else {
return false;
}
}
void ModbusTcpClient::onConnected()
{
qDebug() << "Connected to Modbus TCP server";
}
void ModbusTcpClient::onDisconnected()
{
qDebug() << "Disconnected from Modbus TCP server";
}
void ModbusTcpClient::onError(QAbstractSocket::SocketError error)
{
qDebug() << "Modbus TCP socket error:" << error << "-" << m_socket->errorString();
}
void ModbusTcpClient::onReadyRead()
{
qDebug() << "Modbus TCP socket ready to read";
}
void ModbusTcpClient::sendRequest(const QByteArray &data)
{
m_socket->write(data);
}
bool ModbusTcpClient::parseResponse(const QByteArray &data, QVector<quint16> &values)
{
ModbusTcpHeader header = *reinterpret_cast<const ModbusTcpHeader *>(data.constData());
if (header.unitId != 1 || header.length < 3) {
return false;
}
ModbusTcpResponse response;
response.byteCount = data[9];
response.data = data.mid(10);
if (response.byteCount != response.data.length()) {
return false;
}
for (int i = 0; i < response.byteCount; i += 2) {
quint16 value = (static_cast<quint8>(response.data[i]) << 8) | static_cast<quint8>(response.data[i + 1]);
values.append(value);
}
return true;
}
```
使用示例:
```cpp
ModbusTcpClient client;
client.connectToServer("192.168.1.100", 502);
QVector<quint16> values;
bool success = client.readHoldingRegisters(1, 0, 10, values);
if (success) {
qDebug() << "Read holding registers succeeded:" << values;
} else {
qDebug() << "Read holding registers failed";
}
```
阅读全文