0 背景
就算是TCP传输,也会存在因为网络不稳定或其他原因,导致传输到客户端的数据丢失了部分数据,导致拆包的时候,无法正常拆包(比如帧头带的长度显示整个帧体(包括帧头的长度是10个字节),但是实际收到的只有7个长度,这就会导致把下一帧的枕头错误的读3个字节到上一帧的帧体中,导致数据错位,)。那如何处理呢?
1 解决
丢掉本次接收的接收的数据,也就是进行一次下面的操作,然后再按正常拆包流程继续拆包:
QTcpSocket* tcpSocket;
tcpSocket->readAll();
但是这样的做法十分不科学,会导致丢失大量的数据。
合理的做法是继续往下寻找合法的帧头:
QByteArray data = tcpSocket->readAll();
QByteArray m_cache = data;
//记录帧头的位置
int headSeq=0;
while(findhead(m_cache,headSeq))
{
//移除前面非法数据
m_cache.remove(0,headSeq);
//把剩余的合法带帧头的套接字加在下一次处理的套接字里面
//code
}
寻找合法帧头:
bool findhead(QByteArray &buffer, int &index)
{
char * ptr= buffer.data();
int i =0;
int frameLength = 4;//帧头长度
for(i = 0;i < buffer.size()- frameLength;++i)
{
/*
* 找到头部,并将头部所在下标传给index
*/
//依次寻找合法帧头
if((quint8)ptr[i] == (quint8)0xff &&
(quint8)ptr[i+1] == (quint8)0xcb &&
(quint8)ptr[i+2] ==(quint8)0xbc &&
(quint8)ptr[i+3] == (quint8)0xff)
{
index = i;
return true;
}
}
return false;
}