一个C++版的网络数据包解析策略
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; 之前保存这个数据片,并在和下次接收的拼接解析数据长度。
此策略不是最好的更不是最优的,更好的可能就在你那里呢,有你的指点我相信会更好的。
一个C++版的网络数据包解析策略的更多相关文章
- C++版的网络数据包解析策略(升级版)
初版:http://www.cnblogs.com/wjshan0808/p/6580638.html 说明:在实现了对应的接口后该策略可以适合绝大多数的网络数据包结构 首先,是三个接口 IProdu ...
- 发现新大陆:一个最简单的破解SSL加密网络数据包的方法
1. 简介 相信能访问到这篇文章的同行基本上都会用过流行的网络抓包工具WireShark,用它来抓取相应的网络数据包来进行问题分析或者其他你懂的之类的事情. 一般来说,我们用WireShark来抓取包 ...
- 一个最简单的通过WireShark破解SSL加密网络数据包的方法
原文地址: http://article.yeeyan.org/view/530101/444688 一般来说,我们用WireShark来抓取包进行分析是没有多大问题的.但这里有个问题是,如果你碰到的 ...
- 【VS开发】使用WinPcap编程(4)——把网络数据包存储到一个文件中
这里用到的数据结构是pcap_dumper_t,这也是一个相当于文件描述符的东西,我们在用的时候先指定pcap_dumper_t *dumpfp; 使用两个函数来存储网络数据,一个是pcap_dump ...
- LINUX下的远端主机登入 校园网络注册 网络数据包转发和捕获
第一部分:LINUX 下的远端主机登入和校园网注册 校园网内目的主机远程管理登入程序 本程序为校园网内远程登入,管理功能,该程序分服务器端和客户端两部分:服务器端为remote_server_udp. ...
- sk_buff封装和解封装网络数据包的过程详解(转载)
http://dog250.blog.51cto.com/2466061/1612791 可以说sk_buff结构体是Linux网络协议栈的核心中的核心,几乎所有的操作都是围绕sk_buff这个结构体 ...
- linux2.6.24内核源代码分析(2)——扒一扒网络数据包在链路层的流向路径之一
在2.6.24内核中链路层接收网络数据包出现了两种方法,第一种是传统方法,利用中断来接收网络数据包,适用于低速设备:第二种是New Api(简称NAPI)方法,利用了中断+轮询的方法来接收网络数据包, ...
- 用C++实现网络编程---抓取网络数据包的实现方法
一般都熟悉sniffer这个工具,它可以捕捉流经本地网卡的所有数据包.抓取网络数据包进行分析有很多用处,如分析网络是否有网络病毒等异常数据,通信协议的分析(数据链路层协议.IP.UDP.TCP.甚至各 ...
- UNIX网络编程——网络数据包检测
网络数据包检测 数据包捕获(sniffer):是指在网络上进行数据收集的行为,需要通过网卡来完成. 三种访问方式: BSD Packet Filter(BPF) SVR4 Datalink Provi ...
随机推荐
- Java实现 LeetCode 118 杨辉三角
118. 杨辉三角 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 5 输出: [ [1], [1,1], ...
- Android如何使用SQLlite数据库
先写一个类,继承自SQLiteOpenHelper public class MyDatabaseHelper extends SQLiteOpenHelper { //声明一个Context pri ...
- Java实现空瓶换汽水
1 空瓶换汽水 浪费可耻,节约光荣.饮料店节日搞活动:不用付费,用3个某饮料的空瓶就可以换一瓶该饮料.刚好小明前两天买了2瓶该饮料喝完了,瓶子还在.他耍了个小聪明,向老板借了一个空瓶,凑成3个,换了一 ...
- 掌握SpringBoot-2.3的容器探针:深入篇
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创分类汇总及配套源码,涉及Java.Docker.K8S.DevOPS等 关于<Spr ...
- C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!(应该是全网第一篇)
一:背景 1. 讲故事 好消息,.NET 5.0 终于在2020年6月10日发布了第五个预览版,眼尖的同学一定看到了在这个版本中终于支持了 C# 9.0,此处有掌声,太好了!!! .Net5官方链接 ...
- Redis的内存和实现机制
1. Reids内存的划分 数据 内存统计在used_memory中 进程本身运行需要内存 Redis主进程本身运行需要的内存占用,代码.常量池等 缓冲内存,客户端缓冲区.复制积压缓冲区.AOF缓冲区 ...
- <VCC笔记> 溢出与unchecked
在程序运算或者数据转换的时候,由于各种数据类型有各自的范围,运算的时候,其结果如果超出这个范围,就被称之为溢出.熟悉C#的同志们应该了解用来解决溢出(Overflow)问题的checked,unche ...
- JavaScript常用项目(更新至19.11.17)
目录 项目一:鼠标拖动方块 项目二:网页显示键入字母 项目三:实现滚播图 项目四: 本地数据记事本 项目一:鼠标拖动方块 代码: <!DOCTYPE html> <html> ...
- 8种排序算法 Java实现
冒泡排序 O(n2) 两个数比较大小,较大的数下沉,较小的数冒起来. public static void bubbleSort(int[] a) { //临时变量 int temp; //i是循环次 ...
- 附017.Kubernetes_v1.17.4 Dashboard部署
一 Kubernetes dashboard简介 1.1 Web UI简介 dashboard是基于Web的Kubernetes用户界面.可以使用dashboard将容器化应用程序部署到Kuberne ...