一个C++版的网络数据包解析策略
2024-09-01 13:21:24
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; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。
此策略不是最好的更不是最优的,更好的可能就在你那里呢,有你的指点我相信会更好的。
最新文章
- zabbix3.0.4 部署之七 (zabbix3.0.4 邮件报警) &; 微信报警
- android 内存查看的不同数据指标
- flexbox布局
- 【SVN多用户开发】代码冲突&;解决办法
- DotNetCore跨平台~Startup类的介绍
- sql2005 全文索引
- java里有没有专门判断List里有重复的数据
- C#动态调用C++编写的DLL函数
- 转载:C#中事件的由来
- hdu 1196
- iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
- 【Android中Broadcast Receiver组件具体解释 
】
- javascript模拟鼠标双击事件
- oracle知识点总结基础篇1
- CodeForces 1151D Stas and the Queue at the Buffet
- 【原创】Mysql中select的正确姿势
- Task使用
- Django urls 路由
- Codeforces 524E Rooks and Rectangles 线段树
- Spring之配置文件中引入其它配置文件