C++版的网络数据包解析策略(升级版)
初版:http://www.cnblogs.com/wjshan0808/p/6580638.html
说明:在实现了对应的接口后该策略可以适合绝大多数的网络数据包结构
首先,是三个接口
IProduceProxy.h
#ifndef _I_PRODUCE_PROXY_H_
#define _I_PRODUCE_PROXY_H_ //Code
#define CODE_PRODUCE_PROXY_OK 0x00 //OK
#define CODE_PRODUCE_PROXY_NI 0x01 //Not Implemented
#define CODE_PRODUCE_PROXY_NT 0x02 //Nothing
#define CODE_PRODUCE_PROXY_RY 0x0F //Ready //INTERFACE
class CIProduceProxy
{
public:
virtual int ProduceProxy(char* &szBuffer, int &nBufferLength) = ;
}; //PFN
typedef int(CIProduceProxy::*PFN_PRODUCEPROXY)(char* &szBuffer, int &nBufferLength); #endif //_I_PRODUCE_PROXY_H_
IStrategyProtocol.h
#ifndef _I_STRATEGY_PROTOCOL_H_
#define _I_STRATEGY_PROTOCOL_H_ //CODE
#define CODE_STRATEGY_PROTOCOL_OK 0x00 //OK
#define CODE_STRATEGY_PROTOCOL_NI 0x01 //Not Implemented
#define CODE_STRATEGY_PROTOCOL_ML 0x02 //Miss Length
#define CODE_STRATEGY_PROTOCOL_RY 0x0F //Ready //INTERFACE
class CIStrategyProtocol
{
public:
virtual int ExtractLength(const char* szBuffer, int nBufferLength, int &nExtractLength) = ;
}; //PFN
typedef int (CIStrategyProtocol::*PFN_STRATEGYPROTOCOL)(const char* szBuffer, int nBufferLength, int &nExtractLength); #endif //_I_STRATEGY_PROTOCOL_H_
IConsumeProxy.h
#ifndef _I_CONSUME_PROXY_H_
#define _I_CONSUME_PROXY_H_ //Code
#define CODE_CONSUME_PROXY_OK 0x00 //OK
#define CODE_CONSUME_PROXY_NI 0x01 //Not Implemented
#define CODE_CONSUME_PROXY_RY 0x0F //Ready //INTERFACE
class CIConsumeProxy
{
public:
virtual int ConsumeProxy(const char* szBuffer, int nBufferLength) = ;
}; //PFN
typedef int(CIConsumeProxy::*PFN_CONSUMEPROXY)(const char* szBuffer, int nBufferLength); #endif //_I_CONSUME_PROXY_H_
然后,例如我们有如下一个协议对象,实现IStrategyProtocol接口
.h
#ifndef _PROTOCOL_H_
#define _PROTOCOL_H_ #include "IStrategyProtocol.h" class CProtocol : public CIStrategyProtocol
{
public:
CProtocol();
~CProtocol(); public:
int ExtractLength(const char* szBuffer, int nBufferLength, int &nExtractLength) override; }; #endif //_PROTOCOL_H_
.cpp
#include "Protocol.h" CProtocol::CProtocol()
{
}
CProtocol::~CProtocol()
{
} int CProtocol::ExtractLength(const char* szBuffer, int nBufferLength, int &nExtractLength)
{
nExtractLength = ; if (false)
return CODE_STRATEGY_PROTOCOL_ML; //... return CODE_STRATEGY_PROTOCOL_OK;
}
其次,例如我们有如下的网络端对象,实现IProduceProxy,IConsumeProxy接口
.h
#ifndef _NET_CLIENT_H_
#define _NET_CLIENT_H_ #include "ExtractTask.h"
#include "Protocol.h" class CNetClient : public CIProduceProxy, public CIConsumeProxy
{
public:
CNetClient();
~CNetClient(); public:
int Init();
int Receive(char* szReceiveBuffer, int nBufferLength);
int Processing(const char* szData, int nDataLength); public:
int ProduceProxy(char* &szBuffer, int &nBufferLength) override;
int ConsumeProxy(const char* szBuffer, int nBufferLength) override; private:
CExtractTask* m_pExtractor;
CProtocol* m_pProtocol;
}; #endif //_DRIVE_M_40064900_H_
.cpp
#include "NetClient.h" CNetClient::CNetClient()
{
m_pProtocol = new CProtocol();
m_pExtractor = new CExtractTask();
}
CNetClient::~CNetClient()
{
} int CNetClient::Init()
{
m_pExtractor->Proxies(this, this->m_pProtocol, this); return ;
} int CNetClient::ProduceProxy(char* &szBuffer, int &nBufferLength)
{
nBufferLength = Receive(szBuffer, nBufferLength);
if (nBufferLength <= )
return CODE_PRODUCE_PROXY_NT;
return CODE_PRODUCE_PROXY_OK;
} int CNetClient::ConsumeProxy(const char* szBuffer, int nBufferLength)
{
Processing(szBuffer, nBufferLength);
return CODE_CONSUME_PROXY_OK;
}
最终是我们的解析策略实现对象
.h
#ifndef _EXTRACT_TASK_H_
#define _EXTRACT_TASK_H_ #include "IStrategyProtocol.h"
#include "IProduceProxy.h"
#include "IConsumeProxy.h" class CExtractTask
{
public:
CExtractTask();
virtual ~CExtractTask(); public:
int Proxies(CIProduceProxy* pProducer, CIStrategyProtocol* pStrategy, CIConsumeProxy* pConsumer);
//int Proxies(PFN_PRODUCEPROXY pfnProducer, PFN_STRATEGYPROTOCOL pfnStrategy, PFN_CONSUMEPROXY pfnConsumer); protected:
virtual int ProduceImply(char* &szBuffer, int &nBufferLength);
virtual int StrategyImply(const char* szBuffer, int nBufferLength, int &nExtractLength);
virtual int ConsumeImply(const char* szExtractCopier, int nExtractLength); private:
int Extractor(); private:
CIProduceProxy* m_pProducer;
//PFN_PRODUCEPROXY m_pfnProducer;
CIStrategyProtocol* m_pStrategy;
//PFN_STRATEGYPROTOCOL m_pfnStrategy;
CIConsumeProxy* m_pConsumer;
//PFN_CONSUMEPROXY m_pfnConsumer;
}; #endif //_EXTRACT_TASK_H_
.cpp
#include "ExtractTask.h"
#include <cstring>
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif //WIN32 #define TIME_BASE_UNIT_VALUE 1000
#define TIME_TASK_SLEEP_16MS 16
#ifdef WIN32
#define TIME_EXTRACT_8MS 8
#else
#define TIME_EXTRACT_8MS (8 * TIME_BASE_UNIT_VALUE)
#endif // WIN32 #define LENGTH_EXTRACT_BUFFER (1024 * 4) //接收缓冲区大小 using namespace std; CExtractTask::CExtractTask() :
m_pProducer(NULL), m_pStrategy(NULL), m_pConsumer(NULL)
//, m_pfnProducer(NULL), m_pfnStrategy(NULL), m_pfnConsumer(NULL)
{
}
CExtractTask::~CExtractTask(void)
{
/*
m_pfnProducer = NULL;
m_pfnStrategy = NULL;
m_pfnConsumer = NULL;
*/
/*
if (m_pProducer != NULL)
delete m_pProducer;
if (m_pStrategy != NULL)
delete m_pStrategy;
if (m_pConsumer != NULL)
delete m_pConsumer;
*/
} int CExtractTask::Proxies(CIProduceProxy* pProducer, CIStrategyProtocol* pStrategy, CIConsumeProxy* pConsumer)
{
m_pProducer = pProducer;
m_pStrategy = pStrategy;
m_pConsumer = pConsumer; return ;
}
/*
int CExtractTask::Proxies(PFN_PRODUCEPROXY pfnProducer, PFN_STRATEGYPROTOCOL pfnStrategy, PFN_CONSUMEPROXY pfnConsumer)
{
m_pfnProducer = pfnProducer;
m_pfnStrategy = pfnStrategy;
m_pfnConsumer = pfnConsumer; return 0;
}
*/
int CExtractTask::ProduceImply(char* &szBuffer, int &nBufferLength)
{
if (m_pProducer == NULL)// && m_pfnProducer == NULL)
return CODE_PRODUCE_PROXY_NI; if (m_pProducer != NULL)
return m_pProducer->ProduceProxy(szBuffer, nBufferLength);
//else if (m_pfnProducer != NULL)
// return m_pfnProducer(szBuffer, nBufferLength); return CODE_PRODUCE_PROXY_RY;
} int CExtractTask::StrategyImply(const char* szBuffer, int nBufferLength, int &nExtractLength)
{
if (m_pStrategy == NULL)// && m_pfnStrategy == NULL)
return CODE_STRATEGY_PROTOCOL_NI; if (m_pStrategy != NULL)
return m_pStrategy->ExtractLength(szBuffer, nBufferLength, nExtractLength);
//else if (m_pfnStrategy != NULL)
// return m_pfnStrategy(szBuffer, nBufferLength, nExtractLength); return CODE_STRATEGY_PROTOCOL_RY;
} int CExtractTask::ConsumeImply(const char* szExtractCopier, int nExtractLength)
{
if (m_pConsumer == NULL)// && m_pfnConsumer == NULL)
return CODE_CONSUME_PROXY_NI; if (m_pConsumer != NULL)
return m_pConsumer->ConsumeProxy(szExtractCopier, nExtractLength);
//else if (m_pfnConsumer != NULL)
// return m_pfnConsumer(szExtractCopier, nExtractLength); return CODE_CONSUME_PROXY_RY;
} int CExtractTask::Extractor()
{
int nSurplusLength = ;
char* szExtractCopier = NULL;
char* szExtractCopyIterator = NULL;
//Extract Buffer from Product Proxy.
do
{
//Extract Buffer
char* szExtractBuffer = new char[LENGTH_EXTRACT_BUFFER]();
//Extract Length
int nExtractBufferLength = LENGTH_EXTRACT_BUFFER;
//Productor Proxy
int nRet = ProduceImply(szExtractBuffer, nExtractBufferLength);
if (nRet != CODE_PRODUCE_PROXY_OK)
{
//LogMessage(LOGLEVEL_DEBUG, "ProduceProxy Return(%d).", nRet);
delete[] szExtractBuffer;
break;
}
//LogMessage(LOGLEVEL_INFO, "ProduceProxy Extract Buffer-Length(%d).", nExtractBufferLength); //Clone Extractor to extract
char* szExtractor = szExtractBuffer;
//Begin to Extract by The Rules
do
{
//Surplus Length less than or equal to zero that Means new could be create
if (nSurplusLength <= )
{
//Got Extract-Length from RuleProxy(Extract Whole Length)
int nExtractLength = ;
nRet = StrategyImply(szExtractor, nExtractBufferLength, nExtractLength);
if (nRet != CODE_STRATEGY_PROTOCOL_OK)
{
break;
}
//To new that Means variate value is equal between nSurplusLength and nExtractLength.
nSurplusLength = nExtractLength; //Allocate enough space for new
szExtractCopier = new char[nExtractLength + ]();
//Mark Movable Pointer for Copier
szExtractCopyIterator = szExtractCopier;
}
//when ExtractBufferLength is less than SurplusLength that Means Data copy is continue
if (nExtractBufferLength < nSurplusLength)
{
//Doing copy
memcpy(szExtractCopyIterator, szExtractor, nExtractBufferLength);
//Move ExtractCopyIterator position
szExtractCopyIterator += nExtractBufferLength;
//Cut down SurplusLength
nSurplusLength -= nExtractBufferLength;
//Move Extractor position
szExtractor += nExtractBufferLength;
//Cut down ExtractBufferLength
nExtractBufferLength -= nExtractBufferLength;
}
else//(nExtractBufferLength >= nSurplusLength)
{
//Doing copy
memcpy(szExtractCopyIterator, szExtractor, nSurplusLength);
//Move Extractor position
szExtractor += nSurplusLength;
//Cut down ExtractBufferLength
nExtractBufferLength -= nSurplusLength;
//Move ExtractCopyIterator position
szExtractCopyIterator += nSurplusLength;
//Cut down SurplusLength
nSurplusLength -= nSurplusLength;
//Package Whole Length
ConsumeImply(szExtractCopier, (szExtractCopyIterator - szExtractCopier));
//Clean szExtractCopier
delete[] szExtractCopier;
szExtractCopier = NULL;
}
} while (nExtractBufferLength > );
//Clean szExtractBuffer
delete[] szExtractBuffer; #ifdef WIN32
Sleep(TIME_EXTRACT_8MS);
#else
usleep(TIME_EXTRACT_8MS);
#endif // WIN32
} while (!m_bStopStream);
//Clean szExtractCopier
if (szExtractCopier != NULL)
delete[] szExtractCopier;
return ;
}
C++版的网络数据包解析策略(升级版)的更多相关文章
- 一个C++版的网络数据包解析策略
C++版的网络数据包解析策略(升级版) 一.数据包格式形如下图 二.代码 int ReceiveFromRemoteEndPoint() { int nPackageDataLength = ; ch ...
- LINUX下的远端主机登入 校园网络注册 网络数据包转发和捕获
第一部分:LINUX 下的远端主机登入和校园网注册 校园网内目的主机远程管理登入程序 本程序为校园网内远程登入,管理功能,该程序分服务器端和客户端两部分:服务器端为remote_server_udp. ...
- Linux 中的网络数据包捕获
Linux 中的网络数据包捕获 Ashish Chaurasia, 工程师 简介: 本教程介绍了捕获和操纵数据包的不同机制.安全应用程序,如 VPN.防火墙和嗅探器,以及网络应用程序,如路由程序,都依 ...
- 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.甚至各 ...
- Android利用tcpdump和wireshark抓取网络数据包
Android利用tcpdump和wireshark抓取网络数据包 主要介绍如何利用tcpdump抓取andorid手机上网络数据请求,利用Wireshark可以清晰的查看到网络请求的各个过程包括三次 ...
- UNIX网络编程——网络数据包检测
网络数据包检测 数据包捕获(sniffer):是指在网络上进行数据收集的行为,需要通过网卡来完成. 三种访问方式: BSD Packet Filter(BPF) SVR4 Datalink Provi ...
- 发现新大陆:一个最简单的破解SSL加密网络数据包的方法
1. 简介 相信能访问到这篇文章的同行基本上都会用过流行的网络抓包工具WireShark,用它来抓取相应的网络数据包来进行问题分析或者其他你懂的之类的事情. 一般来说,我们用WireShark来抓取包 ...
随机推荐
- Java实现 蓝桥杯VIP 算法训练 一元三次方程
问题描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差 ...
- Java实现 蓝桥杯 算法提高 双十一抢购
试题 算法提高 双十一抢购 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 一年一度的双十一又来了,某网购网站又开始了半价销售的活动. 小G打算在今年的双十一里尽情地购物,以享受购买 ...
- PAT A除以B
本题要求计算A/B,其中A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数Q 和余数R,使得 A=B*Q+R 成立. 输入格式: 输入在一行中依次给出A 和B,中间以 1 空格分 ...
- 经典文本特征表示方法: TF-IDF
引言 在信息检索, 文本挖掘和自然语言处理领域, IF-IDF 这个名字, 从它在 20 世纪 70 年代初被发明, 已名震江湖近半个世纪而不曾衰歇. 它表示的简单性, 应用的有效性, 使得它成为不同 ...
- 【asp.net core】7 实战之 数据访问层定义
0. 前言 在上一篇,我们搭建了一个项目框架,基本上是一个完整的项目.目前而言,大部分的应用基本都是这个结构.好的,不废话了,进入今天的议题:完成并实现数据层的基础实现. 1. 数据实体 通常情况下, ...
- 学习Redis好一阵了,我对它有了一些新的看法
前言 本篇文章不是一篇具体的教程,我打算记录一下自己对Redis的一些思考.说来惭愧,我刚接触Redis的时候只是简单地使用了一下,背了一些面试题,就在简历上写下了Redis这个技能点. 我们能在网络 ...
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- 传递函数-微分方程-差分方程-Matlab阶跃响应曲线
Transfer function: 1 ------- 5 s + 1 写成微分方程: 5y'(t)+y(t)=u(t) 向前差分: 5y(k+1)+(T-5)y(k)=Tu(k) T:Sample ...
- zabbix服务的部署
1.zabbix的介绍 zabbix是一个基于WEB界面分布式系统监视以及网络监视功能的企业的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并且提供灵活的通知机制以让系统管 ...
- 最后一面挂在volatile关键字上,面试官:重新学学Java吧!
最后一面挂在volatile关键字上,面试官:重新学学Java吧! 为什么会有volatile关键字? volatile: 易变的; 无定性的; 无常性的; 可能急剧波动的; 不稳定的; 易恶化的; ...