qt linux封包,QTcpSocket 通讯 ( 服务器、客户端、封包、解包 )

该代码段展示了如何处理TCP套接字的数据读取和解析,特别是针对可能出现的粘包情况。`OnReadyRead`函数监听并读取socket数据,`parsePacket`函数则用于解析包含包头、包长度、数据类型和包尾的数据包。当数据不足或者包尾不匹配时,代码会处理这种情况并尝试继续解析后续数据。
摘要由CSDN通过智能技术生成

// 读取 socket 数据

void SocketClient::OnReadyRead()

{

QTcpSocket *socket = qobject_cast(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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值