QTcpSocket 通讯 ( 服务器、客户端、封包、解包 )
来源:互联网 发布:广告算法工程师招聘 编辑:程序博客网 时间:2024/06/12 13:03
转载请注明出处:http://blog.csdn.net/lthcth111/article/details/78175341
一、简介
简单实现 QTcpSocket 通讯,包含有服务器、客户端界面,和封包、解包过程,示例界面如下。
二、数据包结构
注:长度 = sizeof( 包类型 + 数据 + 包尾 )
三、部分代码展示
- 封包
// 封包并发送void SocketClient::send(QByteArray data, QByteArray dataType){ QTcpSocket *socket = m_dataSocket; if(socket == NULL || (socket != NULL && socket->state() != QTcpSocket::ConnectedState)) { return; } QByteArray packet = dataType + data + NET_PACKET_END; //[包类型 + 数据 + 包尾] //长度占8字节,前面补零,如"00065536" int size = packet.size(); QByteArray length = QByteArray().setNum(size); length = QByteArray(NET_PACKET_LTNGTH_BYTES, '0') + length; length = length.right(NET_PACKET_LTNGTH_BYTES); packet.insert(0, NET_PACKET_START + length);//插入 [包头 + 数据长度] socket->write(packet);}
- 解包
// 读取 socket 数据void SocketClient::OnReadyRead(){ QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender()); if(socket == m_dataSocket ) { m_dataPacket.data += socket->readAll(); // 循环解析包数据,m_dataPacket.data 中可能不只一包数据 bool isOk = false; do{ isOk = parsePacket(socket, &m_dataPacket); }while(isOk); } else { MY_LOG("socket connection abnormal"); }}// 解包bool SocketClient::parsePacket(QTcpSocket *socket, SocketPacket *packet){ int pIndexStart = packet->data.indexOf(NET_PACKET_START); if(pIndexStart < 0) { return false; } packet->data = packet->data.mid(pIndexStart); //截取从包头index_start到末尾的数据 SocketPacket tmpPacket; tmpPacket.data = packet->data; tmpPacket.data.remove(0, QByteArray(NET_PACKET_START).size());//删除包头 //解析包长度 if(tmpPacket.data.count() < NET_PACKET_LTNGTH_BYTES) { return false; } bool isOk; tmpPacket.length = tmpPacket.data.mid(0, NET_PACKET_LTNGTH_BYTES).toLong(&isOk); if(isOk == false) { packet->data.remove(0, QByteArray(NET_PACKET_START).size());//删除包头 if(packet->data.indexOf(NET_PACKET_START) >= 0) { return true;//有可能出现粘包的情况,继续解析后面数据 } else { return false; } } //数据到达包长度 tmpPacket.data.remove(0, NET_PACKET_LTNGTH_BYTES);//删除数据长度 if(tmpPacket.length > tmpPacket.data.count()) { return false; } //包尾是否匹配 tmpPacket.data.resize(tmpPacket.length);//删除多余数据 if(tmpPacket.data.endsWith(NET_PACKET_END) == false) { packet->data.remove(0, QByteArray(NET_PACKET_START).size());//删除包头 if(packet->data.indexOf(NET_PACKET_START) >= 0) { return true;//有可能出现粘包的情况,继续解析后面数据 } else { return false; } } tmpPacket.data.resize(tmpPacket.length - QByteArray(NET_PACKET_END).count()); //删除包尾 //解析出数据类型 if(tmpPacket.data.count() < NET_PACKET_TYPE_BYTES) { return false; } QByteArray dataType = tmpPacket.data.left(NET_PACKET_TYPE_BYTES); tmpPacket.dataType = dataType; tmpPacket.data.remove(0, NET_PACKET_TYPE_BYTES);//删除数据类型 //发送数据包消息 if(socket == m_dataSocket) { emit dataPacketReady(tmpPacket); } //删除当前包数据 packet->data.remove(0, QByteArray(NET_PACKET_START).size() + NET_PACKET_LTNGTH_BYTES + tmpPacket.length); return true;}
四、完整代码下载
CSDN 下载客户端和服务器:http://download.csdn.net/download/lthcth111/10011256
码云下载服务器:https://gitee.com/2649549484/TcpServerSimple客户端:https://gitee.com/2649549484/TcpClientSimple
五、开发环境
Win7 + Qt 5.5.0
阅读全文
0 0
- QTcpSocket 通讯 ( 服务器、客户端、封包、解包 )
- QTcpSocket类 客户端/服务器模式
- 封包解包?
- scoket通讯过程中的封包,解包与异或加密等
- 客户端和服务器通讯 方法(1)
- 客户端和服务器通讯 方法(2)
- 服务器--客户端通讯
- QTcpServer与QTcpSocket通讯
- tcp封包才,解包
- CC2541 AirSync(4)——封包、解包
- UDP通讯:服务器与客户端
- 封包的截取与解包-3
- 封包的截取与解包-2
- 封包的截取与解包-1
- UMXT协议封包/解包示例
- 使用serialization 进行封包、解包
- iOS/Android JSON封包与解包
- UDP通讯(客户端)
- Warm up HDU
- 设计模式_策略模式(16)
- 单词翻转
- WebServer服务器原理(例子)
- Android 6.0 运行时权限处理 二维码开发
- QTcpSocket 通讯 ( 服务器、客户端、封包、解包 )
- java开发/10.1-10.3/邓聪
- 微信公众号title替换
- Java编程思想读书笔记——持有对象
- IntelliJ 添加JRebel 实现 Tomcat热部署
- POJ 2992 Divisors(求组合数因子个数)
- C++判断出栈顺序
- C++构造函数简述
- 一个合格的程序员应该读过哪些书