首页 > 代码库 > 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_
View Code

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_
View Code

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_
View Code

然后,例如我们有如下一个协议对象,实现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_
View Code

.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;} 
View Code

其次,例如我们有如下的网络端对象,实现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_
View Code

.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;} 
View Code

最终是我们的解析策略实现对象
.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_
View Code

.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++版的网络数据包解析策略(升级版)