数据分包处理

点击打开链接

[cpp]  view plain copy
  1. #ifndef __DIVPACK_H__  
  2. #define __DIVPACK_H__  
  3.   
  4. #pragma once  
  5.   
  6.   
  7. typedef int (*pfnProcessPackCallback)(const char*, intvoid*);  
  8.   
  9. class TDivPack  
  10. {  
  11. public:  
  12.     TDivPack()  
  13.     {  
  14.         maxlen = 0;  
  15.         szpack = NULL;  
  16.         Reset();  
  17.     }  
  18.     ~TDivPack()  
  19.     {  
  20.         if(szpack != NULL)  
  21.         {  
  22.             free(szpack);  
  23.             szpack = NULL;  
  24.         }  
  25.     }  
  26.   
  27.     void Reset()  
  28.     {  
  29.         bunbroken=true;  
  30.         npacklen = 0;  
  31.         ncurlen = 0;  
  32.         nleftlen = 0;  
  33.     }  
  34.   
  35.     void DivPack(const char* pbuf, int nsize, pfnProcessPackCallback ProcessCallback, void* pVoid)  
  36.     {  
  37.         if(nsize <= 0)  
  38.             return;  
  39.   
  40.         if(!bunbroken)  
  41.         {  
  42.             // 当前包数据没有接收完全,继续处理接收  
  43.             // 首先计算前一个包还需要多少数据  
  44.             int nleft = npacklen - ncurlen;  
  45.             if(nleft > nsize)  
  46.             {  
  47.                 // 如果当前包还能容纳的数据大于传入的数据,将数据附加到当前包尾  
  48.                 memcpy(szpack+ncurlen, pbuf, nsize);  
  49.                 // 更新当前包的接收长度  
  50.                 ncurlen += nsize;  
  51.             }  
  52.             else  
  53.             {  
  54.                 // 如果当前包还能容纳的数据小于或等于传入的数据,将数据附加到当前包尾  
  55.                 memcpy(szpack+ncurlen, pbuf, nleft);  
  56.                 // 标记产生一个完整的包, 进行处理  
  57.                 if(ProcessCallback != NULL)  
  58.                 {  
  59.                     (*ProcessCallback)(szpack, npacklen, pVoid);  
  60.                 }  
  61.   
  62.                 bunbroken = true;  
  63.                 npacklen = 0;  
  64.                 // 继续处理剩余数据  
  65.                 DivPack(pbuf+nleft, nsize - nleft, ProcessCallback, pVoid);  
  66.             }  
  67.         }  
  68.         else  
  69.         {  
  70.             // 重置当前包的数据标记  
  71.             ncurlen = 0;  
  72.             bunbroken = true;  
  73.   
  74.             if( nsize < (4-nleftlen) )  
  75.             {  
  76.                 // 如果当前传入的数据长度小于 解析包长度所需的字节数,保存数据  
  77.                 memcpy(((char*)&npacklen)+nleftlen, pbuf, 4-nleftlen);    
  78.                 nleftlen += nsize;  
  79.                 return;  
  80.             }  
  81.   
  82.             // 解析数据包长度  
  83.             memcpy(((char*)&npacklen)+nleftlen, pbuf, 4-nleftlen);  
  84.   
  85.             // 创建数据缓存,并初始化0  
  86.             if(szpack == NULL)  
  87.             {  
  88.                 szpack = (char*)malloc(npacklen);  
  89.                 maxlen = npacklen;  
  90.             }  
  91.   
  92.             // 为减少内存分配次数,当包长度大于当前缓存长度时才重新分配  
  93.             if(npacklen > maxlen)  
  94.             {  
  95.                 szpack = (char*)realloc(szpack, npacklen);  
  96.             }  
  97.               
  98.             memset(szpack, 0, npacklen);  
  99.   
  100.             // 记录实际数据包偏移  
  101.             int noffset = 4-nleftlen;  
  102.             nleftlen = 0;  
  103.   
  104.             // 计算传入数据包剩余长度  
  105.             int nleft = nsize - noffset;  
  106.   
  107.             if(nleft < npacklen)  
  108.             {  
  109.                 // 如果传入的长度小于数据包长度  
  110.                 // 设置数据包位不完整包,并记录已缓存的数据长度  
  111.                 ncurlen = nleft;  
  112.                 bunbroken = false;  
  113.                 // 拷贝数据  
  114.                 memcpy(szpack, pbuf+4, nleft);  
  115.             }  
  116.             else  
  117.             {  
  118.                 // 如果传入长度大于数据包长度,拷贝数据  
  119.                 memcpy(szpack, pbuf+noffset, npacklen);  
  120.                 // 标记产生一个完整的包, 进行处理  
  121.                 if(ProcessCallback != NULL)  
  122.                 {  
  123.                     (*ProcessCallback)(szpack, npacklen, pVoid);  
  124.                 }  
  125.                 bunbroken = true;  
  126.                 int ntemplen = npacklen;  
  127.                 npacklen = 0;  
  128.                 // 继续处理剩余数据  
  129.                 DivPack(pbuf+ntemplen+noffset, nsize-ntemplen-noffset, ProcessCallback, pVoid);  
  130.             }  
  131.         }  
  132.     }  
  133.   
  134. private:  
  135.     char*   szpack;  
  136.     bool    bunbroken;  
  137.     int     npacklen;  
  138.     int     ncurlen;  
  139.     int     nleftlen;  
  140.     int     maxlen;  
  141. };  
  142.   
  143.   
  144. #endif // __DIVPACK_H__  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值