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++版的网络数据包解析策略的更多相关文章

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

    初版:http://www.cnblogs.com/wjshan0808/p/6580638.html 说明:在实现了对应的接口后该策略可以适合绝大多数的网络数据包结构 首先,是三个接口 IProdu ...

  2. 发现新大陆:一个最简单的破解SSL加密网络数据包的方法

    1. 简介 相信能访问到这篇文章的同行基本上都会用过流行的网络抓包工具WireShark,用它来抓取相应的网络数据包来进行问题分析或者其他你懂的之类的事情. 一般来说,我们用WireShark来抓取包 ...

  3. 一个最简单的通过WireShark破解SSL加密网络数据包的方法

    原文地址: http://article.yeeyan.org/view/530101/444688 一般来说,我们用WireShark来抓取包进行分析是没有多大问题的.但这里有个问题是,如果你碰到的 ...

  4. 【VS开发】使用WinPcap编程(4)——把网络数据包存储到一个文件中

    这里用到的数据结构是pcap_dumper_t,这也是一个相当于文件描述符的东西,我们在用的时候先指定pcap_dumper_t *dumpfp; 使用两个函数来存储网络数据,一个是pcap_dump ...

  5. LINUX下的远端主机登入 校园网络注册 网络数据包转发和捕获

    第一部分:LINUX 下的远端主机登入和校园网注册 校园网内目的主机远程管理登入程序 本程序为校园网内远程登入,管理功能,该程序分服务器端和客户端两部分:服务器端为remote_server_udp. ...

  6. sk_buff封装和解封装网络数据包的过程详解(转载)

    http://dog250.blog.51cto.com/2466061/1612791 可以说sk_buff结构体是Linux网络协议栈的核心中的核心,几乎所有的操作都是围绕sk_buff这个结构体 ...

  7. linux2.6.24内核源代码分析(2)——扒一扒网络数据包在链路层的流向路径之一

    在2.6.24内核中链路层接收网络数据包出现了两种方法,第一种是传统方法,利用中断来接收网络数据包,适用于低速设备:第二种是New Api(简称NAPI)方法,利用了中断+轮询的方法来接收网络数据包, ...

  8. 用C++实现网络编程---抓取网络数据包的实现方法

    一般都熟悉sniffer这个工具,它可以捕捉流经本地网卡的所有数据包.抓取网络数据包进行分析有很多用处,如分析网络是否有网络病毒等异常数据,通信协议的分析(数据链路层协议.IP.UDP.TCP.甚至各 ...

  9. UNIX网络编程——网络数据包检测

    网络数据包检测 数据包捕获(sniffer):是指在网络上进行数据收集的行为,需要通过网卡来完成. 三种访问方式: BSD Packet Filter(BPF) SVR4 Datalink Provi ...

随机推荐

  1. Java实现 LeetCode 89 格雷编码

    89. 格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异. 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列.格雷编码序列必须以 0 开头. 示例 1: 输 ...

  2. Java实现 蓝桥杯VIP 算法提高 企业奖金发放

    算法提高 企业奖金发放 时间限制:1.0s 内存限制:512.0MB 企业发放的奖金根据利润提成.利润低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10% ...

  3. java实现测量到的工程数据

    [12,127,85,66,27,34,15,344,156,344,29,47,-] 这是某设备测量到的工程数据. 因工程要求,需要找出最大的 5 个值. 一般的想法是对它排序,输出前 5 个.但当 ...

  4. Java实现填写乘法算式

    观察下面的算式: * * × * * = * * * 它表示:两个两位数字相乘,结果是3位数.其中的星号(*)代表任意的数字,可以相同,也可以不同,只要不是在首位的就可以是0.当然,满足这个要求的算式 ...

  5. tensorflow2.0学习笔记第一章第一节

    一.简单的神经网络实现过程 1.1张量的生成 # 创建一个张量 #tf.constant(张量内容,dtpye=数据类型(可选)) import tensorflow as tf import num ...

  6. Vue封装公共组件TarBar

    github:https://github.com/zwnsyw/TabBar 一.实现简单思路 1.在页面底部有一个单独的TabBar组件1.1自定义TabBar组件,在APP中使用1.2让TabB ...

  7. 环境篇:呕心沥血@CDH线上调优

    环境篇:呕心沥血@线上调优 为什么出这篇文章? 近期有很多公司开始引入大数据,由于各方资源有限,并不能合理分配服务器资源,和服务器选型,小叶这里将工作中的总结出来,给新入行的小伙伴带个方向,不敢说一定 ...

  8. 为什么要使用Mybatis-现有持久化技术的对比

    1)JDBC SQL 夹在Java代码块里,耦合度高导致硬编码内伤 维护不易且实际开发需求中SQL有变化,频繁修改的情况很多 2)Hibernate 和 JPA 长难复杂SQL, 对于Hibernat ...

  9. 面试必问系列之JDK动态代理

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  10. 8.eclipse 安装 lombook插件

    参考博客:https://www.liangzl.com/get-article-detail-129979.html