您的位置:首页 > 其它

数据分包处理

2011-07-08 09:52 381 查看
#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__
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: