zoukankan      html  css  js  c++  java
  • 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) = 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
    
    //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_
    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
    
    //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_
    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;
    }
  • 相关阅读:
    特征归一化
    什么是端到端(end2end)学习?
    RSA加密原理及其证明
    python脚本中__all__变量的用法
    洛谷 1108 低价购买
    洛谷 3029 [USACO11NOV]牛的阵容Cow Lineup
    洛谷 1365 WJMZBMR打osu! / Easy
    洛谷 2759 奇怪的函数
    洛谷 2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    牛客网NOIP赛前集训营 提高组 第5场 T2 旅游
  • 原文地址:https://www.cnblogs.com/wjshan0808/p/7269606.html
Copyright © 2011-2022 走看看