C++实现网络服务器命令模式(设计及模板实现)

Client->request Server->response模式的网络服务器中,对应答的处理一般是采用switch模式。

此方法比较难于维护,且缺少错误检测。

本文采用C++模板实现一套较为通用的服务器命令处理模型。

阅读本文你应该对C++模板较为熟悉。

ok,进入正题。

假定客户命令包头为。

struct MsgHead{

DWORD type;

};

定义客户端命令模板类。

template<DWORD reqCode>

class RequestT:protected MsgHead{

STATIC_CHECK(0,REQUEST_NOT_DEFINED);

};

定义宏对具体命令做偏特化。

#define DECL_REQUEST(reqCode)/

template<>/

class RequestT<reqCode>:public MsgHead{/

friend class RequestHandlerT<reqCode>;/   //处理函数

RequestT<reqCode>(){}

#define END_DECL(code)/

};

定义回应类

template<DWORD resCode,DWORD reqCode>

class ResponseT:protected MsgHead{

STATIC_CHECK(0,REQUEST_NOT_DEFINED);

};

偏特化

#define DECL_RESPONSE(reqCode,resCode)/

template<>/

class ResponseT<resCode>:public MsgHead{/

friend class RequestHandlerT<reqCode>;/   //处理函数

ResponseT<resCode>(){type=resCode;}

定义处理函数.

typedef  int CommandHandler(MsgHead* in,MsgHead* out);

处理函数模板

template <DWORD code>

class HandlerT{

static int Handle(MsgHead*in,MsgHead* out);

};

定义命令映射表格

struct cmd_set{

DWORD dwRequest;

CommandHandler* pHandler;

};

定义命令映射宏

#define MAP_CMD(code)/

{code, HandlerT<code>::Handle},

ok,整个架构以基本搭建好了。

现在来写一个简单的命令处理试试。

//客户端请求

enum{

CR_CONNECT,

};

//服务器回应

enum{

SR_OK,

SR_DENY

};

//请求包格式

DECL_REQUEST(CR_CONNECT)

WORD wReason;

DWORD dwVerify;

END_DECL(CR_CONNECT)

//成功回应格式

DECL_RESPONSE(CR_CONNECT,SR_OK)

DWORD dwConnectionID

END_DECL(CR_CONNECT)

//拒绝包回应格式

DECL_RESPONSE(CR_CONNECT,SR_DENY)

DWORD    dwError;

END_DECL(CR_CONNECT)

//处理函数

template<>

class HandlerT<CR_CONNECT>{

static int Handle(MsgHead*in,MsgHead*out){

MsgRequestT<CR_CONNECT>* pIn=static_cast<MsgRequest<CR_CONNECT>*>(in);

switch(pIn.wReason){

......

}

.....

return out包长度

}

}

建立映射表

cmd_set Cmd_MAP[]={

MAP_CMD(CR_CONNECT)

..................

};

主函数中通过wType查找Cmd_MAP找到处理函数后调用函数处理包。

//==============================================================================

上面的模型可以用宏进一步减少工作量。(如HandlerT<>等)

另外MsgHead及其派生类(各种request/response)都不应该允许被实例化,否则处理函数可能出错(处理函数并不知道实际可写包长)。

可以将MsgHead构造函数声明为protected的。只将可以被实例化的实际子类声明为public.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值