C++版的网络数据包解析策略(升级版)

一、数据包格式形如下图

二、代码

int ReceiveFromRemoteEndPoint()
{
int nPackageDataLength = ;
char *szPackageCleaner = NULL;
char *szPackageIterator = NULL;
do
{
char *szReceiveArray = new char[RECEIVED_BUFFER_LENGTH]();
int nReceiveLength = RECEIVED_BUFFER_LENGTH;
nReceiveLength = Receive(szReceiveArray, nReceiveLength, TIMEOUT);
if (nReceiveLength <= )
{
Log("Recveived Time-Out(%d)...", nReceiveLength);
delete[] szReceiveArray;
break;
}
Log("Received (%d) Bytes", nReceiveLength); char *szReceive = szReceiveArray; do
{
if(nPackageDataLength == )
{
if(szReceive[] != HEADER)
{
Log("Package Data Header-Analysis Error, Size(%d).", nReceiveLength);
break;
}
if(nReceiveLength < PACKHEADERLENGTH)
{
Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength);
break;
} //offset HEADER length
char *szPackageDataLength = szReceive + sizeof(char); //包数据的长度(不包含包头长度)
LengthResolve(szPackageDataLength, nPackageDataLength); szPackageCleaner = new char[nPackageDataLength + PACKHEADERLENGTH + ]();
szPackageIterator = szPackageCleaner; memcpy(szPackageIterator, szReceive, PACKHEADERLENGTH);
szPackageIterator += PACKHEADERLENGTH; szReceive += PACKHEADERLENGTH;
nReceiveLength -= PACKHEADERLENGTH;
}
//已接收的包数据长度 < 包数据长度 = 一个不完整的包
if(nReceiveLength < nPackageDataLength)
{
memcpy(szPackageIterator, szReceive, nReceiveLength); szPackageIterator += nReceiveLength;
nPackageDataLength -= nReceiveLength; szReceive += nReceiveLength;
nReceiveLength -= nReceiveLength;
}
else//(nReceiveLength >= nPackageDataLength)
{
//已接收的包数据长度 == 包数据长度 = 一个完整的包
//已接收的包数据长度 > 包数据长度 = 至少有一个完整的包 + 至少一个数据片段
memcpy(szPackageIterator, szReceive, nPackageDataLength);
//szPackageIterator += nPackageDataLength;
Resolve(szPackageCleaner, (szPackageIterator - szPackageCleaner) + nPackageDataLength); szReceive += nPackageDataLength;
nReceiveLength -= nPackageDataLength; nPackageDataLength = ; delete[] szPackageCleaner;
szPackageCleaner = NULL;
} }while(nReceiveLength > ); delete[] szReceiveArray;
Sleep(); }while(IsStop);//Receiving if(szPackageCleaner != NULL)
delete[] szPackageCleaner; return ;
}

三、说明

网络数据包接收,最好是有超时机制的,比如2秒左右。

if(nReceiveLength < PACKHEADERLENGTH)
{
Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength);
//这里会出现些问题
break;
}

问题描述:
  假如一个完整的数据包解析后,剩余的接收长度 < PACKHEADERLENGTH, 即包头HEADER校验正确,但是解析包数据长度的时接收到的数据不足以解析出

数据要接收的长度。此策略会丢弃包数据至下一个正确的包被正确解析,这个和缓冲区设置的长度是没有直接关系的,当然长度要大于PACKHEADERLENGTH.

要解决这个问题,可以在 break; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。

此策略不是最好的更不是最优的,更好的可能就在你那里呢,有你的指点我相信会更好的。

最新文章

  1. zabbix3.0.4 部署之七 (zabbix3.0.4 邮件报警) &amp; 微信报警
  2. android 内存查看的不同数据指标
  3. flexbox布局
  4. 【SVN多用户开发】代码冲突&amp;解决办法
  5. DotNetCore跨平台~Startup类的介绍
  6. sql2005 全文索引
  7. java里有没有专门判断List里有重复的数据
  8. C#动态调用C++编写的DLL函数
  9. 转载:C#中事件的由来
  10. hdu 1196
  11. iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
  12. 【Android中Broadcast Receiver组件具体解释 】
  13. javascript模拟鼠标双击事件
  14. oracle知识点总结基础篇1
  15. CodeForces 1151D Stas and the Queue at the Buffet
  16. 【原创】Mysql中select的正确姿势
  17. Task使用
  18. Django urls 路由
  19. Codeforces 524E Rooks and Rectangles 线段树
  20. Spring之配置文件中引入其它配置文件

热门文章

  1. Java实现 蓝桥杯VIP 算法训练 整除问题
  2. java实现第六届蓝桥杯饮料换购
  3. Python学习之输入输出入门 A+B篇
  4. k8s学习-Ingress
  5. [转] Git caret(^) and tilde(~)
  6. MSSQL(DAC环境一下一些特殊的访问方式)
  7. Java8新特性之方法引用
  8. LeetCode 78,面试常用小技巧,通过二进制获得所有子集
  9. IDEA之maven配置详解
  10. yii2.0数据库操作