2023年8月3日发(作者:)
QT中TCP通信及遇到的问题以⾃定数据包格式进⾏通信数据包格式如下:服务端代码如下:。cpp⽂件:主界⾯程序会发送emit sendTime()和emit sendOCRMsg(OCRMsg, dateTime)信号对应HeratPack和sendData槽函数#include "TCPthread.h"#include
//监听套接字,指定⽗对象,让其⾃动回收空间 tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::AnyIPv4, 8888); //当有客服端连接时 connect(tcpServer, &QTcpServer::newConnection,this,&TCPthread::createSocket);//-----------------------------------------------------------------------------------------------}void TCPthread::createSocket() { //取出建⽴好连接的套接字 QTcpSocket *tcpSocket = tcpServer->nextPendingConnection(); _back(tcpSocket); //获取客户端的IP和端⼝ QString ip = tcpSocket->peerAddress().toString(); qint16 port = tcpSocket->peerPort(); IPort = QString("TCPClient-[%1:%2]:成功连接").arg(ip).arg(port); qDebug() << IPort; connect(tcpSocket, &QTcpSocket::connected, [=]() { qDebug() << "成功和服务器建⽴好连接"; }); //接受客服端的数据 connect(tcpSocket, &QTcpSocket::readyRead,this, &TCPthread::readData); //当客户端断开连接 connect(tcpSocket, &QTcpSocket::disconnected, this, &TCPthread::clientDiscon);}//从客户端读取数据void TCPthread::readData() { //从通信套接字中取出内容 if (() != 0) { for (int i = 0; i < (); i++) { QByteArray array = socketList[i]->readAll();
} }}//客户端断开连接void TCPthread::clientDiscon() { //与服务器连接的客户端 QTcpSocket *tcpsocket = qobject_cast
//封装包头 QByteArray sendOCRByte;//⽤于发送数据的字节数组 QDataStream out(&sendOCRByte, QIODevice::WriteOnly);//使⽤数据流写⼊数据 eOrder(QDataStream::LittleEndian);//设置⼩端模式 out << ushort(0) << m_OCRPackID;//占位符,这⾥必须要先这样占位,然后后续读算出整体长度后在插⼊ qDebug() << "报⽂头长度:" << ();//4 //封装数据 QString s_data = OCR_Msg + ng("yyyy-MM-dd hh:mm:") +"0"; qDebug() << s_data << "字符串长度:" << s_();//48 QByteArray ba = s_l8Bit(); //字符串转字节数组 qDebug() << "字符字节数组长度:" << (); //48//--------------------------------------------------------- char * c_data; c_data = (); (c_data);//在4个字节数组中添加48个字符串//--------------------------------------------------------- ()->seek(0);//回到数据流开头,插⼊数据的长度
ushort t_len = (ushort)(()); out << t_len; qDebug() << "板坯报⽂长度:" << t_len;//52 //发送数据|多例 if (() != 0) { for (int i = 0; i < (); i++) { socketList[i]->write(sendOCRByte); socketList[i]->flush(); } }}//发送⼼跳报⽂void TCPthread::HeratPack() { if (() != 0) { for (int i = 0; i < (); i++) { //⽤于⼼跳报⽂要发送的数据 QByteArray sendHeartByte; //使⽤数据流写⼊数据 QDataStream out(&sendHeartByte, QIODevice::WriteOnly); //设置⼩端模式 eOrder(QDataStream::LittleEndian); //占位符,这⾥必须要先这样占位,然后后续读算出整体长度后在插⼊ out << ushort(0) << m_heartPackID ; //回到⽂件开头,插⼊数据的长度
()->seek(0); ushort len = (ushort)(()); out << len;//4
qDebug() <<"⼼跳报⽂长度:" << len << "⼼跳报⽂ID:" << m_heartPackID; //往套接字缓存中写⼊数据,并发送 socketList[i]->write(sendHeartByte); socketList[i]->flush(); } }}TCPthread::~TCPthread(){ //主动和客户端断开连接 if (() != 0) { for (int i = 0; i < (); i++) { socketList[i]->disconnectFromHost(); socketList[i]->close(); socketList[i] = NULL; delete socketList[i]; } } delete tcpServer;
}遇到的问题:1、⼼跳报⽂中为发送4个字节长度报⽂:两个quint16类型的数据均占2个字节,甲⽅并要求使⽤⼩端模式解决办法:使⽤QByteArray字节数组进⾏写⼊2、数据报⽂中,需使⽤ushort类型2个占4个字节和48个字节字符串共52个字节解决办法:前⾯ushort类型使⽤QDataStraem类型写到QByteArray中。后⾯字符串使⽤char *类型append添加到QByteArray中,这样共52个字节客户端:读取数据。cpp⽂件:#include "Client.h"#pragma execution_character_set("utf-8")Client::Client(QWidget *parent) : QWidget(parent){ i(this);}//连接按钮|获取服务器地址和端⼝号void Client::on_Connect_Button_clicked(){ socket = new QTcpSocket(this); socket->connectToHost(->text(),->text().toInt()); connect(socket,SIGNAL(readyRead()),this,SLOT(receiveMessage()));}//发送按钮|获取⽂本框内容void Client::on_Send_Button_clicked(){ QString str = ->toPlainText(); socket->write(8());//中⽂不乱码}//接收信息显⽰void Client::receiveMessage(){ qDebug() << socket->bytesAvailable() << "========";//452 if (socket->bytesAvailable() <= 0) { return; } QByteArray buffer; buffer = socket->readAll(); //m_(buffer); qDebug() << (); //4或者52 if (() == 4) { QString s = (4); if (s == "ABC" ) { //QString str = QString(buffer); ive->append(s); } qDebug() << (0,2).toInt(); //0 qDebug() << (2, 2).toInt();//0 QDataStream packet(buffer); eOrder(QDataStream::LittleEndian); quint16 len, ID; packet >> len >>ID; qDebug() << len < ive->append(QString::number(len)); //4 ive->append(QString::number(ID)); //1 } if (() == 52) { /*quint16 length = (quint16)(0,2).toInt(); quint16 packID = (quint16)(2, 2).toInt();*/ //qDebug() << "报⽂长度:" << length << " 报⽂ID:" << packID;//报⽂长度: 4 报⽂ID: 0 //--------------------------------------------------------------------------------------- QDataStream OCRpacket(buffer); eOrder(QDataStream::LittleEndian); quint16 ocr_length, ocr_ID; OCRpacket >> ocr_length >> ocr_ID; qDebug() << "报⽂长度2:" << ocr_length << " 报⽂ID2:" << ocr_ID; //-------------------------------------------------------------------------------------------- QString OCRstr = QString::fromStdString((4, 24).toStdString()); qDebug() << OCRstr; QString s_dateTome = QString::fromStdString((28, 52).toStdString()); qDebug() << s_dateTome; ive->append(OCRstr); ive->append(s_dateTome); }
2023年8月3日发(作者:)
QT中TCP通信及遇到的问题以⾃定数据包格式进⾏通信数据包格式如下:服务端代码如下:。cpp⽂件:主界⾯程序会发送emit sendTime()和emit sendOCRMsg(OCRMsg, dateTime)信号对应HeratPack和sendData槽函数#include "TCPthread.h"#include
//监听套接字,指定⽗对象,让其⾃动回收空间 tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::AnyIPv4, 8888); //当有客服端连接时 connect(tcpServer, &QTcpServer::newConnection,this,&TCPthread::createSocket);//-----------------------------------------------------------------------------------------------}void TCPthread::createSocket() { //取出建⽴好连接的套接字 QTcpSocket *tcpSocket = tcpServer->nextPendingConnection(); _back(tcpSocket); //获取客户端的IP和端⼝ QString ip = tcpSocket->peerAddress().toString(); qint16 port = tcpSocket->peerPort(); IPort = QString("TCPClient-[%1:%2]:成功连接").arg(ip).arg(port); qDebug() << IPort; connect(tcpSocket, &QTcpSocket::connected, [=]() { qDebug() << "成功和服务器建⽴好连接"; }); //接受客服端的数据 connect(tcpSocket, &QTcpSocket::readyRead,this, &TCPthread::readData); //当客户端断开连接 connect(tcpSocket, &QTcpSocket::disconnected, this, &TCPthread::clientDiscon);}//从客户端读取数据void TCPthread::readData() { //从通信套接字中取出内容 if (() != 0) { for (int i = 0; i < (); i++) { QByteArray array = socketList[i]->readAll();
} }}//客户端断开连接void TCPthread::clientDiscon() { //与服务器连接的客户端 QTcpSocket *tcpsocket = qobject_cast
//封装包头 QByteArray sendOCRByte;//⽤于发送数据的字节数组 QDataStream out(&sendOCRByte, QIODevice::WriteOnly);//使⽤数据流写⼊数据 eOrder(QDataStream::LittleEndian);//设置⼩端模式 out << ushort(0) << m_OCRPackID;//占位符,这⾥必须要先这样占位,然后后续读算出整体长度后在插⼊ qDebug() << "报⽂头长度:" << ();//4 //封装数据 QString s_data = OCR_Msg + ng("yyyy-MM-dd hh:mm:") +"0"; qDebug() << s_data << "字符串长度:" << s_();//48 QByteArray ba = s_l8Bit(); //字符串转字节数组 qDebug() << "字符字节数组长度:" << (); //48//--------------------------------------------------------- char * c_data; c_data = (); (c_data);//在4个字节数组中添加48个字符串//--------------------------------------------------------- ()->seek(0);//回到数据流开头,插⼊数据的长度
ushort t_len = (ushort)(()); out << t_len; qDebug() << "板坯报⽂长度:" << t_len;//52 //发送数据|多例 if (() != 0) { for (int i = 0; i < (); i++) { socketList[i]->write(sendOCRByte); socketList[i]->flush(); } }}//发送⼼跳报⽂void TCPthread::HeratPack() { if (() != 0) { for (int i = 0; i < (); i++) { //⽤于⼼跳报⽂要发送的数据 QByteArray sendHeartByte; //使⽤数据流写⼊数据 QDataStream out(&sendHeartByte, QIODevice::WriteOnly); //设置⼩端模式 eOrder(QDataStream::LittleEndian); //占位符,这⾥必须要先这样占位,然后后续读算出整体长度后在插⼊ out << ushort(0) << m_heartPackID ; //回到⽂件开头,插⼊数据的长度
()->seek(0); ushort len = (ushort)(()); out << len;//4
qDebug() <<"⼼跳报⽂长度:" << len << "⼼跳报⽂ID:" << m_heartPackID; //往套接字缓存中写⼊数据,并发送 socketList[i]->write(sendHeartByte); socketList[i]->flush(); } }}TCPthread::~TCPthread(){ //主动和客户端断开连接 if (() != 0) { for (int i = 0; i < (); i++) { socketList[i]->disconnectFromHost(); socketList[i]->close(); socketList[i] = NULL; delete socketList[i]; } } delete tcpServer;
}遇到的问题:1、⼼跳报⽂中为发送4个字节长度报⽂:两个quint16类型的数据均占2个字节,甲⽅并要求使⽤⼩端模式解决办法:使⽤QByteArray字节数组进⾏写⼊2、数据报⽂中,需使⽤ushort类型2个占4个字节和48个字节字符串共52个字节解决办法:前⾯ushort类型使⽤QDataStraem类型写到QByteArray中。后⾯字符串使⽤char *类型append添加到QByteArray中,这样共52个字节客户端:读取数据。cpp⽂件:#include "Client.h"#pragma execution_character_set("utf-8")Client::Client(QWidget *parent) : QWidget(parent){ i(this);}//连接按钮|获取服务器地址和端⼝号void Client::on_Connect_Button_clicked(){ socket = new QTcpSocket(this); socket->connectToHost(->text(),->text().toInt()); connect(socket,SIGNAL(readyRead()),this,SLOT(receiveMessage()));}//发送按钮|获取⽂本框内容void Client::on_Send_Button_clicked(){ QString str = ->toPlainText(); socket->write(8());//中⽂不乱码}//接收信息显⽰void Client::receiveMessage(){ qDebug() << socket->bytesAvailable() << "========";//452 if (socket->bytesAvailable() <= 0) { return; } QByteArray buffer; buffer = socket->readAll(); //m_(buffer); qDebug() << (); //4或者52 if (() == 4) { QString s = (4); if (s == "ABC" ) { //QString str = QString(buffer); ive->append(s); } qDebug() << (0,2).toInt(); //0 qDebug() << (2, 2).toInt();//0 QDataStream packet(buffer); eOrder(QDataStream::LittleEndian); quint16 len, ID; packet >> len >>ID; qDebug() << len < ive->append(QString::number(len)); //4 ive->append(QString::number(ID)); //1 } if (() == 52) { /*quint16 length = (quint16)(0,2).toInt(); quint16 packID = (quint16)(2, 2).toInt();*/ //qDebug() << "报⽂长度:" << length << " 报⽂ID:" << packID;//报⽂长度: 4 报⽂ID: 0 //--------------------------------------------------------------------------------------- QDataStream OCRpacket(buffer); eOrder(QDataStream::LittleEndian); quint16 ocr_length, ocr_ID; OCRpacket >> ocr_length >> ocr_ID; qDebug() << "报⽂长度2:" << ocr_length << " 报⽂ID2:" << ocr_ID; //-------------------------------------------------------------------------------------------- QString OCRstr = QString::fromStdString((4, 24).toStdString()); qDebug() << OCRstr; QString s_dateTome = QString::fromStdString((28, 52).toStdString()); qDebug() << s_dateTome; ive->append(OCRstr); ive->append(s_dateTome); }
发布评论