游戏开发论坛

 找回密码
 立即注册
搜索
查看: 11237|回复: 12

网络游戏中网络模块浅析

[复制链接]

3

主题

11

帖子

20

积分

注册会员

Rank: 2

积分
20
发表于 2010-4-12 21:25:00 | 显示全部楼层 |阅读模式
原文:http://blog.csdn.net/deletex/archive/2010/03/10/5365545.aspx


在网络游戏中,不论是服务端还是客户端都需要网络通讯的功能模块,而一个优秀的成熟的网络通讯模块,又可以用于多个游戏产品中。



于是,在学习的过程中,设计和实现一个可复用的网络通讯模块,变得非常的有意义。

        

         通过思考我们可以一步一步的来实现这样的模块:



我们应该知道对原生的 Socket API 进行封装是有必要的,也许当前服务端是运行在 window 环境下,也许改天就有可能要在 Linux 下面运行。而对原生 Socket API 进行封装,可以很方便的让我们进行两者的切换,并且不需要我们付出多大的代价。

可以像下面这样封装 , 放在 SOCKET_API 命名空间下面 , 其他 API 类似:

UINT SOCKET_API:: recv_ex ( SOCKET s , void * buf , UINT len , UINT flags )

{

         #if defined __LINUX__

              … .

#elif defined __WINDOWS__

              … .

#endif

}



我们都知道游戏通常都是使用 TCP 来实现通讯的 , 而 TCP 需要下面这些最基本的功能及对 SOCKET 进行设置或者获取信息的函数。

server
       

client

bind

listen

accept

send

recv

close
       

connect

send

recv

close

我们希望把这些功能都封闭到一个 CSocket 类中。

class CSocket

{

public :

     构造函数, 析构函数, 初始化函数 ……

     BOOL connect (const CHAR * host , UINT port ) ;

              UINT send (const VOID * buf , UINT len , UINT flags = 0) ;

     SOCKET accept ( struct sockaddr * addr , UINT * addrlen ) ;

其他函数, 例如receive ,bind,listen,close,get 和set 变量接口,有效性判断等等 ……

public :

              SOCKET m_SocketID ;

              SOCKADDR_IN m_SockAddr ;

              CHAR m_Host [IP_SIZE ];

              UINT m_Port ;

};

不论是服务端还是客户端都没有办法做到一收到消息就马上响应请求,然后直接把

这个消息丢弃掉。所以我们需要有一个地方可以保存这些消息,这时我们可以定义输入和输出消息缓冲区的类,当我们发送或者接收消息时,先把消息放到相应的消息缓冲区里,然后再进行相应的处理。而这个缓冲区最好是环形的,当缓冲区不够用的时候能够自己增加缓冲区大小,当然需要有个上限。



当我们有了消息缓冲区后,这时我们需要通过一种方式,把消息放入缓冲区和从缓

冲区中把消息读取出来,在放入和取出的时候可能还需要伴随着加密与解密操作。由于在游戏中,一样连接通常都代表着一个玩家。

         我们可以定义个 CPlayer 类 :

class CPlayer

{

public :

         ProcessInput();         // 读取网络上的消息并放在输入消息缓冲区

         ProcessOutput();     // 把输出消息缓冲区中的消息发送出去

         ProcessMsg();          // 处理收到的消息 , 把相应的消息交给相应的处理函数

private :

         输入缓冲区

         输出缓冲区
};



到这里时,上面的内容通常都可以作为服务端和客户端通用的代码。



下面我们重点了解一下,服务端是怎么样接着处理收到的消息的,在我接触过的服务端中,有两种不同的框架,不过处理方式大同小异,顺便提下。



第一种,就像我在 游戏服务端逻辑模块处理框架 中说的差不多,在种情况之下,服务端的逻辑模块会划分成很多的 DLL 模块,比如:


战斗系统就是一个 BattleSys.dll

技能系统就是一个 MagicMgr.dll

角色系统就是一个 RoleMgr.dll


然后我们有一个消息中心 , 当网络模块收到消息之后把消息发送给消息中心,消息中心再把消息 Buffer 发送给感兴趣的 DLL 模块,然后这些 DLL 模块用消息 Buffer 生成相应的 CMsg (每个消息都有消息头,根据消息头的消息编号可以识别相应的 CMsg ) , 并执行 CMsg 的 ProcessMsg 消息处理函数。



第二种,没有把逻辑模块划分成很多个 DLL ,游戏逻辑都在 Server 中进行处理。收到网络消息之后,直接通过管理器类 CpacketFactoryMgr 创建出 CMsg 类(查找相应的消息创建工厂 , 并用它创建出 CMsg 类),并执行 CMsg 的 ProcessMsg 消息处理函数。



其实就是这样的过程,注册 XXX 到管理器 => 通过 XXX 的 ID 到管理器中找到 XXX => XXX.DoSomething()


先写到这里了 … 继续学习之后再继续 ……

34

主题

443

帖子

478

积分

中级会员

Rank: 3Rank: 3

积分
478
发表于 2010-4-12 22:09:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

谢谢分享

0

主题

13

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2010-4-19 16:54:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

楼主所说方法可取,并已有成品框架!
理论上来说,现今的Server技术关注点还是在于稳定上,通用性依然不太强!

12

主题

78

帖子

92

积分

注册会员

Rank: 2

积分
92
发表于 2010-5-7 09:54:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

同意3楼的说法.网络模块的成品框架已有很多. 问题是网络游戏中的其它各个模块.

如果你想用一个CPlayer类就来包含所有玩家的功能. 这本身就是个错误.

它太巨大, 会有成百个方法, 成百个变量. 这对于功能的实现和代码的维护都是一个致命的问题.

重复的调用函数, 重复发送网络消息, 这种情况下, 你底层的网络模块再好, 也不能实现一个良好的服务器程序.

但是,很多公司的服务器就是这样编写的.

把各个模块分解成.dll是个分解功能的办法, 但是你也要考虑各在模块间的沟通问题.

我认为一开始可以不用分成.dll, 关键是先要正确的设计, 要进行全盘的考虑. 尽量细化所有的东西.

然后编写一个概念性的服务器程序.实现所有最基本的功能. 通过压力测试.

做到这一点, 需要丰富的服务器编程经验和充分的时间..






3

主题

263

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2010-6-25 00:17:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

呵呵,楼上说的靠谱.不过工作量巨大.

0

主题

54

帖子

56

积分

注册会员

Rank: 2

积分
56
QQ
发表于 2010-10-7 09:30:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

学习了

0

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2011-1-25 16:25:00 | 显示全部楼层

Re: 网络游戏中网络模块浅析

挺不错的

6

主题

106

帖子

237

积分

中级会员

Rank: 3Rank: 3

积分
237
发表于 2011-1-26 15:36:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

大3的时候在一家小型电信性质的公司实习,有幸参与到他们的网络通信平台底层的架构,发现电信很多成熟的架构对游戏服务器还是有很多借鉴之处的。比如负载均衡、服务器对用户透明化升级(大体是这个意思,术语记不清了)等,最有印象的是他们的子系统接入平台,例如可以接入代理商、短信平台、网上营业厅、客服等。
如果游戏服务器做成单进程,加载不同模块的DLL模式(虽然可以重复起很多),当游戏逻辑增加、在线人数增加到一定程度时,应该就应付不了了吧。
不懂装懂,一点个人想法。见笑。

打个小广告,本人目前就职广东电信某下属子公司,做的是后台服务器一块。欲求客户端等工作,正在自学D3D等。

6

主题

106

帖子

237

积分

中级会员

Rank: 3Rank: 3

积分
237
发表于 2011-1-26 15:45:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

小弟的建议,服务器架构不要局限于send、recv这些函数,重点放在可扩展、安全性、性能、稳定性等方面。一旦定了型,再修改成本是很高的,甚至只能放任。如果有可能,考虑万一这些方面出现问题后在架构、软件、硬件等方面的补救措施。架构好了,编码起来就相当顺手。前期准备越充足,后面的日子才越好过。

0

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2011-3-31 16:00:00 | 显示全部楼层

Re:网络游戏中网络模块浅析

学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 05:26

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表