缓冲区查找包头及包尾偏移
- 前言
- 一、采用动态数组QByteArray的自带函数
- 二、采用字节对比方法
- 测试代码
前言
根据前面所讲的内容封包拆包,当将网络中的数据读出存储在自定义缓冲区QByteArray中,则对数据包进行拆分。则首先要进行的工作就是找到包头的位置及包尾的位置,来判断该包是否完整,下面就来讲两种方法来查找其偏移地址。
一、采用动态数组QByteArray的自带函数
该方法主要就是采用QByteArray的indexOf(const QByteArray &, int)函数,buf表示缓冲区数据,data表示比较包头或包尾的数据,Len表示包头包尾长度。
int Find1(const QByteArray &buf, const char * data, int Len)
{QByteArray array;array.append(data, Len);return buf.indexOf(array);
}
二、采用字节对比方法
该方法主要就是采用字节对比,buf表示缓冲区数据,data表示比较包头或包尾的数据,Len表示包头包尾长度。
int Find2(const QByteArray &buf, const char * data, int Len)
{if (buf.size() < Len){return -1;}const char *temp = buf.data();for (int i = 0; i < buf.size()-Len+1; i++){for (int j = 0; j <= Len; j++){if (j == Len){return i;}if (*(temp+i+j) != *(data+j)){break;}}}
}
测试代码
processor.h:
#pragma pack(1)
#define PACK_HEAD 0xf1f2
#define PACK_TAIL 0xf2f3typedef struct
{short dataHead;long long dataLen;
}HEAD;typedef struct
{short b;int c;long long d;
}DATA;typedef struct
{short daraTail;
}TAIL;#pragma pack()
main.cpp:
#include <QtCore/QCoreApplication>
#include <QtDebug>
#include <QFile>
#include "processor.h"int Find1(const QByteArray &buf, const char *, int Len);
int Find2(const QByteArray &buf, const char * data, int Len);int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);
///创建包结构(模拟接收到网络数据后的缓存区)HEAD head;TAIL tail;QFile file("test.dat"); //二进制文件file.open(QIODevice::ReadOnly);char buf[2*1024];qint64 readLen = file.read(buf,sizeof(buf));head.dataLen = 1400; DATA *param = (DATA *)buf;head.dataHead = PACK_HEAD;tail.daraTail = PACK_TAIL;char *buf1 = new char[8*1024];memcpy(buf1,&head,sizeof(HEAD));memcpy(buf1+sizeof(HEAD),param,readLen);memcpy(buf1+sizeof(HEAD)+readLen,&tail,sizeof(TAIL));int len = sizeof(HEAD)+ readLen + sizeof(TAIL);QByteArray buffer;buffer.append(buf1, len); //缓冲区数据file.close();
if (buffer.size() > sizeof(HEAD)){int headOffset = Find2(buffer, (char *)&head, sizeof(head.dataHead));int tailOffset = Find2(buffer,(char *)&tail, sizeof(tail.daraTail));if (tailOffset-headOffset == len-sizeof(tail.daraTail)){QByteArray headTest= buffer.mid(headOffset,sizeof(HEAD)); //头文件HEAD *packHead = (HEAD *)headTest.data();if (packHead->dataHead == head.dataHead){QByteArray dataTest = buffer.mid(headOffset+sizeof(HEAD),packHead->dataLen);DATA *packData = (DATA *)dataTest.data();qDebug()<<QString::fromLocal8Bit("数据获取成功");}}else{qDebug()<<QString::fromLocal8Bit("数据丢失");}}return a.exec();
}int Find1(const QByteArray &buf, const char * data, int Len)
{QByteArray array;array.append(data, Len);return buf.indexOf(array);
}int Find2(const QByteArray &buf, const char * data, int Len)
{if (buf.size() < Len){return -1;}const char *temp = buf.data();for (int i = 0; i < buf.size()-Len+1; i++){for (int j = 0; j <= Len; j++){if (j == Len){return i;}if (*(temp+i+j) != *(data+j)){break;}}}
}