初版: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) = 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 //INTERFACE class 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 //INTERFACE class 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; }
时间: 2024-12-13 05:51:43