#ifndef __DIVPACK_H__
#define __DIVPACK_H__
#pragma once
typedef int (*pfnProcessPackCallback)(const char*, int, void*);
class TDivPack
{
public:
TDivPack()
{
maxlen = 0;
szpack = NULL;
Reset();
}
~TDivPack()
{
if(szpack != NULL)
{
free(szpack);
szpack = NULL;
}
}
void Reset()
{
bunbroken=true;
npacklen = 0;
ncurlen = 0;
nleftlen = 0;
}
void DivPack(const char* pbuf, int nsize, pfnProcessPackCallback ProcessCallback, void* pVoid)
{
if(nsize <= 0)
return;
if(!bunbroken)
{
// 当前包数据没有接收完全,继续处理接收
// 首先计算前一个包还需要多少数据
int nleft = npacklen - ncurlen;
if(nleft > nsize)
{
// 如果当前包还能容纳的数据大于传入的数据,将数据附加到当前包尾
memcpy(szpack+ncurlen, pbuf, nsize);
// 更新当前包的接收长度
ncurlen += nsize;
}
else
{
// 如果当前包还能容纳的数据小于或等于传入的数据,将数据附加到当前包尾
memcpy(szpack+ncurlen, pbuf, nleft);
// 标记产生一个完整的包, 进行处理
if(ProcessCallback != NULL)
{
(*ProcessCallback)(szpack, npacklen, pVoid);
}
bunbroken = true;
npacklen = 0;
// 继续处理剩余数据
DivPack(pbuf+nleft, nsize - nleft, ProcessCallback, pVoid);
}
}
else
{
// 重置当前包的数据标记
ncurlen = 0;
bunbroken = true;
if( nsize < (4-nleftlen) )
{
// 如果当前传入的数据长度小于 解析包长度所需的字节数,保存数据
memcpy(((char*)&npacklen)+nleftlen, pbuf, 4-nleftlen);
nleftlen += nsize;
return;
}
// 解析数据包长度
memcpy(((char*)&npacklen)+nleftlen, pbuf, 4-nleftlen);
// 创建数据缓存,并初始化0
if(szpack == NULL)
{
szpack = (char*)malloc(npacklen);
maxlen = npacklen;
}
// 为减少内存分配次数,当包长度大于当前缓存长度时才重新分配
if(npacklen > maxlen)
{
szpack = (char*)realloc(szpack, npacklen);
}
memset(szpack, 0, npacklen);
// 记录实际数据包偏移
int noffset = 4-nleftlen;
nleftlen = 0;
// 计算传入数据包剩余长度
int nleft = nsize - noffset;
if(nleft < npacklen)
{
// 如果传入的长度小于数据包长度
// 设置数据包位不完整包,并记录已缓存的数据长度
ncurlen = nleft;
bunbroken = false;
// 拷贝数据
memcpy(szpack, pbuf+4, nleft);
}
else
{
// 如果传入长度大于数据包长度,拷贝数据
memcpy(szpack, pbuf+noffset, npacklen);
// 标记产生一个完整的包, 进行处理
if(ProcessCallback != NULL)
{
(*ProcessCallback)(szpack, npacklen, pVoid);
}
bunbroken = true;
int ntemplen = npacklen;
npacklen = 0;
// 继续处理剩余数据
DivPack(pbuf+ntemplen+noffset, nsize-ntemplen-noffset, ProcessCallback, pVoid);
}
}
}
private:
char* szpack;
bool bunbroken;
int npacklen;
int ncurlen;
int nleftlen;
int maxlen;
};
#endif // __DIVPACK_H__
数据分包处理
最新推荐文章于 2024-01-12 11:48:59 发布