初版: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;
}
原文链接: https://www.cnblogs.com/wjshan0808/p/7269606.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/257728
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!