一个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实现 蓝桥杯VIP 算法训练 学做菜
算法训练 学做菜 时间限制:1.0s 内存限制:256.0MB 问题描述 涛涛立志要做新好青年,他最近在学做菜.由于技术还很生疏,他只会用鸡蛋,西红柿,鸡丁,辣酱这四种原料来做菜,我们给这四种原料标上 ...
- Java实现 蓝桥杯 一步之遥
一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的面前是两个按钮,分别写着"F"和"B". 小明突然记起来,这两个 ...
- Java实现 LeetCode 69 x的平方根
69. x 的平方根 实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: ...
- Java实现 蓝桥杯 历届试题 连号区间数
问题描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增 ...
- Java实现 串中取3个不重复字母
从标准输入读入一个由字母构成的串(不大于30个字符). 从该串中取出3个不重复的字符,求所有的取法. 取出的字符,要求按字母升序排列成一个串. 不同的取法输出顺序可以不考虑. 例如: 输入: abc ...
- MIPI CSI-2
目录 1 MIPI简介 2 MIPI CSI-2简介 2.1 MIPI CSI-2 的层次结构 2.2 CSI-2协议层 2.3 打包/解包层 2.4 LLP(Low Level Protocol)层 ...
- 【Spring注解驱动开发】使用@Lazy注解实现懒加载
写在前面 Spring在启动时,默认会将单实例bean进行实例化,并加载到Spring容器中.也就是说,单实例bean默认在Spring容器启动的时候创建对象,并将对象加载到Spring容器中.如果我 ...
- 3、react-props/state
1.react中属性props和状态state 属性--静态得,所以在初始化得时候使用得是static进行初始化得,正常情况下属性不改 状态--动态得,它得值是可以发生改变得,react中的组件更新( ...
- Python3 源码阅读 - 垃圾回收机制
Python的垃圾回收机制包括了两大部分: 引用计数(大部分在 Include/object.h 中定义) 标记清除+隔代回收(大部分在 Modules/gcmodule.c 中定义) 1. 引用计数 ...
- scws中文分词安装和使用
一.下载源码 wget http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 tar xvjf scws-1.2.3.tar.bz2 二.执行配置 ...