终极网络服务端编程--第二章 【Server框架与消息处理】

原创 2017年09月01日 11:23:21

第二章 Server框架与消息处理

2.1  Server框架

 

现在我们有了网络模块,继续实现服务端Server,上一章,我们的例子代码都是在main.cpp里,如果项目逻辑越来越大,那么main.cpp会很臃肿,这样堆砌代码是不好的,为了良好的设计架构,代码风格,我决定使用面向对象封装,把Server作为一个类,封装后,在main里只有几行代码即可,类似

int _tmain(int argc, _TCHAR* argv[])

{

       Server::GetInstance().Init();

       Server::GetInstance().Run();

}

 

 

Server.h

/********************************************************************/

/*

   Server服务端类

*/

/********************************************************************/

 

class Server

{

       PacketHandler m_PacketHandler;//消息处理

 

       SelectIOServer s;//网络引擎

 

       Server(void);

        

public:

       ~Server(void);

        

       static Server& GetInstance(){

              static Server s;

              return s;

       };

 

       bool Init();

 

       void Run();

 

       BOOL Send(   DWORD dwNetworkIndex ,  BYTE *pMsg,  WORD wSize ){return s.Send(dwNetworkIndex,pMsg,wSize);}

};

 

 

2.2  消息处理

 

 

服务端通讯肯定要定义一大堆消息和数据定义,如果数据消息只有几个,那么在回调接口里if判断几下处理就可以了,但是如果消息成百上千种,那么数据回调函数会很臃肿庞大,势必要用一个单独类来作为消息处理,我使用名称叫PacketHandler的类来专门处理数据消息,它提供一个ParsePacket的方法来负责解析处理数据包,这样在数据回调函数里只要一句代码即可,

PacketHandler.ParsePacket(dwNetworkIndex,pMsg,wSize);

 

PacketHandler.h

 

/********************************************************************/

/*

   消息处理

*/

/********************************************************************/

 

class PacketHandler

{

public:

       PacketHandler(void);

       ~PacketHandler(void);

 

       //处理客户消息

       void ParsePacket(DWORD dwNetworkIndex, BYTE * pMsg,WORD w );

 

       //客户请求登陆

       void On_C2S_LOGIN(DWORD dwNetworkIndex,BYTE * pMsg, WORD w );

};

 

为了演示,我增加了第一个消息,登陆消息。我专门添加一个公用的msgdef.h头文件,放在项目文件夹的公共文件夹下。

msgdef.h里面就只定义我们的消息id和消息结构体。

如下

 

#pragma once

 

 

#define C2S_LOGIN  0        //客户请求登陆

#define S2C_LOGIN_Ret 1       //客户登陆结果

 

 

//客户请求登陆

struct MSG_Login

{

       int cmd; //命令  C2S_LOGIN

       char name[20]; //用户名

       char pwd[20];  //密码

};

 

//客户登陆结果

struct MSG_Login_Ret

{

       int cmd; //命令  S2C_LOGIN_Ret

       int errcode; //1=登陆成功  , 0=登陆失败

       char pwd[20];  //密码

};

 

消息C2S即表示Client to Server,表示客户发送给服务端的。C2S S2C这种定义前缀为了定义方便程序理解和开发。

 

ParsePacket和On_C2S_LOGIN代码如下

 

//处理客户消息

void PacketHandler::ParsePacket(DWORD idx , BYTE * pMsg, WORD wSize )

{

       int  cmd;

       memcpy(&cmd,pMsg,sizeof(cmd));

 

       printf("PacketHandler::ParsePacket  msg %d \n",cmd);

 

       switch (cmd)

       {

              //登陆

       case C2S_LOGIN :          return  On_C2S_LOGIN( idx,pMsg , wSize  );

 

 

       default:

              printf(  "ParsePacket 未知消息id %d\n",cmd);

              break;

       }

}

 

 

//客户请求登陆

void  PacketHandler::On_C2S_LOGIN(DWORD idx,  BYTE * pMsg, WORD wSize )

{

       printf( "On_C2S_LOGIN    %d\n",idx);

 

       MSG_Login s;

       memcpy((char*)&s,  pMsg,  wSize);

 

       //账号abc  密码123456

       if (strcmp(s.name,"abc")==0&& strcmp(s.pwd,"123456")==0 )

       {

              printf(  "登陆成功    %s\n", s.name );

              MSG_Login_Retret;

              ret.cmd=S2C_LOGIN_Ret;

              ret.errcode=1;//登陆成功

 

              Server::GetInstance().Send(idx,(BYTE*)&ret,sizeof(MSG_Login_Ret));

              return ;

       }else{

              printf(  "登陆失败    %s\n", s.name );

              MSG_Login_Retret;

              ret.cmd=S2C_LOGIN_Ret;

              ret.errcode=0; //登陆失败

 

              Server::GetInstance().Send(idx,(BYTE*)&ret,sizeof(MSG_Login_Ret));

              return ;

       }

 

}

 

 

 

客户端也添加一个PacketHandler类 处理Server传递过来的消息。

运行Server再运行Client,运行结果如下,Client登陆成功。

如此,我们消息处理的工作完成了,大家可以以此扩展,添加自己的消息定义以及消息处理。

 

 

 

  

编程交流q群: 316641007

 

相关文章推荐

原创《终极网络服务端编程》pdf+配套源码

历时3个多月,本人编写出《终极网络服务端编程》pdf电子书+配套源码。   本书 《终极网络服务端编程》 主要围绕网络服务端编程技术,编程语言使用c/c++ ,lua,从基础的网络通讯知识讲解,到实...

终极网络服务端编程_pdf.zip

  • 2016年02月05日 10:50
  • 2.31MB
  • 下载

用.Net打造一个移动客户端(Android/IOS)的服务端框架NHM(五)——Android端消息处理机制

一、NhmFramework Android端的消息处理机制原理 1、概要表述:在我们的框架中,Android客户端通过继承Application来控制整个应用程序的生命周期,在Applicatio...

boost库在工作(31)网络服务端之一

上面已经介绍了客户端,接着下来就要开发服务端的程序了,因为只有客户端没有服务端是成不了事的,提供不了网络服务的。像C++这种语言,越来越多的应用都是在网络服务器领域,比如像HTTP服务器、EMAIL服...

boost库在工作(33)网络服务端之三

在这个例子里,表示服务器与一个客户端的沟通渠道,就是一个连接,封装为类CConnect。它是当服务器接收到一个客户端连接请求之后创建的,主要用来就是管理这个连接的生命周期,以及数据的接收和发送。从生命...

arcemu源码(MMORPG网络服务端引擎)

  • 2010年01月04日 16:39
  • 26.04MB
  • 下载

boost库在工作(32)网络服务端之二

在这个例子里,服务器对象主要使用boost::asio::io_service对象,这个对象主要用来构造异步接收数据使用,接着定义boost::asio::ip::tcp::acceptor对象,这个...

oracle网络服务端配置

oracle网络周边配置支持3种应用连接C/S应用连接:sqlplus sys/x2145637@orcljava应用连接Web client应用连接支持的协议TCP/IPTCP/IP with SS...

boost库在工作(32)网络服务端之二

在这个例子里,服务器对象主要使用boost::asio::io_service对象,这个对象主要用来构造异步接收数据使用,接着定义boost::asio::ip::tcp::acceptor对象,这个...

boost库在工作 网络服务端

//封装一个服务端类来处理网络。  //软件开发人员: 蔡军生  2013-07-28  //  class CConnect :       public boost::enable_shared_...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:终极网络服务端编程--第二章 【Server框架与消息处理】
举报原因:
原因补充:

(最多只允许输入30个字)