一个通用网络协议数据解析
Posted 西北老码农
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个通用网络协议数据解析相关的知识,希望对你有一定的参考价值。
1、网络数据解析
我们在实际应用中,网络数据解析是非常常见的一种数据处理方式,那么有没有比较通用的数据解析处理方法呢,以下是个人总结的一种网络数据解析处理方法
2、数据包格式
图1-1是一个比较通用的数据包格式,本次数据解析模型以下图的数据格式为准:
3、代码实现
int ReceiveFromRemoteEndPoint()
int nPackageDataLength = 0;
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 <= 0)
Log("Recveived Time-Out(%d)...", nReceiveLength);
delete[] szReceiveArray;
break;
Log("Received (%d) Bytes", nReceiveLength);
char *szReceive = szReceiveArray;
do
if(nPackageDataLength == 0)
if(szReceive[0] != 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 + 1]();
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 = 0;
delete[] szPackageCleaner;
szPackageCleaner = NULL;
while(nReceiveLength > 0);
delete[] szReceiveArray;
Sleep(8);
while(IsStop);//Receiving
if(szPackageCleaner != NULL)
delete[] szPackageCleaner;
return 0;
4、超时或者异常上报机制
增加超时和异常上报。
5、数据包处理注意事项
if(nReceiveLength < PACKHEADERLENGTH)
Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength);
//这里会出现些问题
break;
假如一个完整的数据包解析后,剩余的接收长度 < PACKHEADERLENGTH, 即包头HEADER校验正确,但是解析包数据长度的时接收到的数据不足以解析出数据要接收的长度。此策略会丢弃包数据至下一个正确的包被正确解析,这个和缓冲区设置的长度是没有直接关系的,当然长度要大于PACKHEADERLENGTH。要解决这个问题,可以在 break; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。
以上是关于一个通用网络协议数据解析的主要内容,如果未能解决你的问题,请参考以下文章