终极网络服务端编程--第二章 【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

 

使用protobuf定义消息

使用protobuf定义消息 下载protobuf-2.3.0:     http://protobuf.googlecode.com/files/protobuf-2.3.0.zip 安装: ...
  • linuxheik
  • linuxheik
  • 2014年04月22日 19:21
  • 771

Linux C 网络编程——多线程的聊天室实现(服务器端)

服务器端的主要功能:        实现多用户群体聊天功能(此程序最多设定为10人,可进行更改),每个人所发送的消息其他用户均可以收到。用户可以随意的加入或退出(推出以字符串“bye”实现),服务器...
  • finish_dream
  • finish_dream
  • 2016年03月22日 22:28
  • 2373

Qt学习心得之网络编程简单的局域网聊天服务端建立

学而不思则罔,思而不学则殆。学习和思考是相辅相成的,通过这几天对网络编程的学习,收获颇丰。接下来我将利用Qt做的一个以TcpIp协议为传输方式的简单的局域网聊天服务端与大家分享下:   首先谈谈我个人...
  • u013144441
  • u013144441
  • 2015年07月26日 10:26
  • 877

Windows网络编程学习笔记(5) TCP服务端向客户端发送Hello World!

Windows下Winsock TCP/IP 网络编程。 本章将详解send()/WSASend() 、 recv()/WSARecv() 和 函数,然后你就可以编写一个可运行的通讯程序了。 程序包括...
  • Raito__
  • Raito__
  • 2016年05月14日 22:55
  • 2205

编程珠玑第二章习题

1、提供单词和词典,找到该单词的所有变位词,可以事先花时间和空间处理下该词典。 因为要查找变位词,事先遍历词典,得到每个单词签名,并建立签名列表,签名列表的每个项包含了该签名的所有单词。有了这个列表,...
  • chenzujie
  • chenzujie
  • 2013年08月10日 11:57
  • 1814

大型网站架构之分布式消息队列

大型网站架构之分布式消息队列   以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统)。 本次分享大纲 消息队列概述消息队列应用场景消息中...
  • shaobingj126
  • shaobingj126
  • 2016年01月26日 08:48
  • 118581

Linux网络编程--TCP网络编程基础(简单的server/client模型)

本文主要讲解C/S模型,对服务器端和客户端的流程和函数的使用进行解析,以及网络编程中对信号的处理,特别是由于连接关闭而产生的SIGPIPE信号和终止进程而产生的SIGINT信号,当然截取信号并进行处理...
  • u010193457
  • u010193457
  • 2015年08月24日 15:25
  • 1688

python网络编程(TCP客户端/服务器端实现)

下面的程序实现的功能:客户端发来消息,服务器端加上时间戳返回给用户 服务器端:from socket import * from time import ctime import osprint(o...
  • u010660276
  • u010660276
  • 2015年11月12日 11:44
  • 2223

Java网络编程的框架

三层架构与MVC的区别三层架构是软件架构,是在整体上将整个软件系统从逻辑上划分为三层,即三个逻辑组件组成,目的是实现组件内的高内聚和组件间的底耦合,这三层分别是,表现层UI,业务逻辑层BLL,数据访问...
  • zilong0536
  • zilong0536
  • 2016年04月30日 20:43
  • 1174

8个java 网络编程框架介绍

自从JDK1.4中有了NIO以后,这个方面越来越活跃,也为java赢得更多开发者的支持。 做java网络编程需要掌握一些基本的知识和技能:套接字编程、阻塞/非阻塞通信、创建HTTP服务器与客...
  • xiaojin21cen
  • xiaojin21cen
  • 2017年11月20日 22:32
  • 223
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:终极网络服务端编程--第二章 【Server框架与消息处理】
举报原因:
原因补充:

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