- #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-07-11 17:44:04 发布