首页 > 代码库 > C++版的网络数据包解析策略(升级版)
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 //INTERFACEclass CIProduceProxy{public: virtual int ProduceProxy(char* &szBuffer, int &nBufferLength) = 0;};//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//INTERFACEclass CIStrategyProtocol{public: virtual int ExtractLength(const char* szBuffer, int nBufferLength, int &nExtractLength) = 0;};//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//INTERFACEclass CIConsumeProxy{public: virtual int ConsumeProxy(const char* szBuffer, int nBufferLength) = 0;};//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 = 0; 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 0;}int CNetClient::ProduceProxy(char* &szBuffer, int &nBufferLength){ nBufferLength = Receive(szBuffer, nBufferLength); if (nBufferLength <= 0) 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 0;}/*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 = 0; 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 <= 0) { //Got Extract-Length from RuleProxy(Extract Whole Length) int nExtractLength = 0; 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 + 1](); //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 > 0); //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 0;}
C++版的网络数据包解析策略(升级版)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。