一个C++版的网络数据包解析策略
C++版的网络数据包解析策略(升级版)
一、数据包格式形如下图
二、代码
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; }
三、说明
网络数据包接收,最好是有超时机制的,比如2秒左右。
if(nReceiveLength < PACKHEADERLENGTH) { Log("Package Data Length-Analysis Error, Size(%d).", nReceiveLength); //这里会出现些问题 break; }
问题描述:
假如一个完整的数据包解析后,剩余的接收长度 < PACKHEADERLENGTH, 即包头HEADER校验正确,但是解析包数据长度的时接收到的数据不足以解析出
数据要接收的长度。此策略会丢弃包数据至下一个正确的包被正确解析,这个和缓冲区设置的长度是没有直接关系的,当然长度要大于PACKHEADERLENGTH.
要解决这个问题,可以在 break; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。
此策略不是最好的更不是最优的,更好的可能就在你那里呢,有你的指点我相信会更好的。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述