这个Qt通讯组件库有点东西。咱们先从底层通讯开始盘——TCP、UDP、Serial三大件全齐活。拿UDP举个栗子,发送报文简单到像发短信
纯qt编写的通讯组件包含tcpudpserialplc客户端有mudbustcpmodbusrtufinstcpfinsudpplc服务端有modbustcp和modbusrtu。 实现其他的plc通信可集成原有基类已封装成pri组件可直接接入工程。 qt5.14.2可直接编译。QUdpSocket* sender new QUdpSocket(this); QByteArray datagram 0x01 0x02 0xA3; sender-writeDatagram(datagram, QHostAddress(192.168.1.100), 9600);但别以为只是简单封装socket接收处理才是重头戏。看看这个异步处理设计connect(udpSocket, QUdpSocket::readyRead, [](){ while(udpSocket-hasPendingDatagrams()) { QByteArray buffer; buffer.resize(udpSocket-pendingDatagramSize()); QHostAddress sender; quint16 senderPort; udpSocket-readDatagram(buffer.data(), buffer.size(), sender, senderPort); emit newMessage(sender.toString(), buffer); } });用Qt的信号槽机制把网络层脏活都包圆了上层业务只管接数据就行。PLC协议这块玩得挺野Modbus和欧姆龙FINS双修。来看个Modbus TCP客户端的典型用法ModbusTCPClient client; client.setConnectionParams(192.168.1.10, 502); if(client.connectDevice()){ QVectorquint16 coilValues; if(client.readCoils(0x00, 10, coilValues)){ qDebug() 线圈状态 coilValues; } }底层实现其实是个状态机模式看看请求封装的关键片段void ModbusTCPClient::sendReadRequest(int functionCode, int startAddr, int quantity) { QByteArray frame; QDataStream stream(frame, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::BigEndian); stream transactionId QByteArray::fromHex(0006) // 协议标识单元号 static_castquint8(functionCode) static_castquint16(startAddr) static_castquint16(quantity); tcpClient-write(frame); // 复用基础TCP连接 }注意这里用大端序处理字节直接关系到能否跟PLC正常对话。协议栈实现时各种字节序转换坑都踩过了现在用着稳如老狗。纯qt编写的通讯组件包含tcpudpserialplc客户端有mudbustcpmodbusrtufinstcpfinsudpplc服务端有modbustcp和modbusrtu。 实现其他的plc通信可集成原有基类已封装成pri组件可直接接入工程。 qt5.14.2可直接编译。扩展性才是这个库的杀手锏。想加个三菱MC协议继承PLCClientBase整就完事class MelsecClient : public PLCClientBase { Q_OBJECT public: explicit MelsecClient(QObject* parentnullptr); protected: void processResponse(const QByteArray data) override { // 解析二进制报文... emit dataUpdated(parsedValues); } void buildReadCommand(int address) override { // 构造三菱特有指令格式... sendRawData(cmdFrame); } };这种设计让协议扩展成本直接打骨折新协议实现只需要关注报文解析逻辑。集成到项目更是傻瓜操作把components.pri往工程里一扔pro文件加句话include(components.pri)然后该咋用咋用连环境变量都不用配。实测Qt5.14.2编译一次过Mingw和MSVC编译器都验证过。要是项目需要升级Qt版本把QSerialPort的旧式信号槽写法改改基本就能跑。库里的连接保活机制有点黑科技TCP自动重连心跳包双保险。看这段连接状态检测void TcpClient::checkConnection() { if(!socket-waitForConnected(500)){ reconnectTimer.start(3000); // 3秒后重试 emit connectionLost(); }else{ socket-write(\x01); // 心跳包 if(!socket-waitForBytesWritten(1000)){ socket-abort(); } } }这种组合拳下来现场设备断网重连什么的根本虚。实测在产线环境掉线后10秒内自动恢复数据流不带断的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2447367.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!