游戏开发入门(十)游戏中的网络模块

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012999985/article/details/79357430

视频链接:游戏开发入门(十)游戏中的网络模块(6节课 时常:约2小时20分钟)
上一节主要针对网络同步的细节与手段进行分析与讲解,这一节除了对一些常见的同步应用场景作解释外更多的会针对偏底层一些的网络内容进行分析。

游戏中的网络与其它软件系统基本原理并无差异,基本上就是解决如何把网络消息快速安全的发送到其他端,然后其他端及时地处理该消息并做出对应的游戏表现。


笔记与总结(请先学习视频内容):

1.服务器在整个游戏过程中是一直运行的
一旦服务器宕,所有的玩家都会掉线,一旦服务器出现卡顿,所有的玩家也会出现卡顿,所以服务器的性能与表现必须非常严格。很多情况下,有一些并非非常重要的逻辑最好放到客户端执行,可以减小服务器压力,而且服务器的内存,CPU性能都要比一般的玩家机器要强的多。

为了减小硬件设施开销,一台服务器机器可能同时运行多个游戏服务器。MMO游戏,局域网游戏以及房间匹配游戏等,各自的服务器网络架构也是不同的,这个需要读者去查阅更多的资料。
推荐链接:https://www.cnblogs.com/hwcs/p/7203605.html
http://gcloud.qq.com/forum/topic/56a0bac3a90d8b775e8f3c1b

2.计算机网络基础——网络模型
这属于计算机基础知识方面的内容,如果不熟悉这一模块,建议先去看一看计算机网络相关书籍,如计算机网络自顶向下方法 https://book.douban.com/subject/1391207/。想进一步深入的话可能需要看TCP/IP详解 卷一卷二卷三,如果对服务器兴趣不是很大或只是想有个大概理解可以先不看这个系列。
这里写图片描述

3.网络游戏开发中我们通常接触的是应用层(游戏逻辑,Socket处理)与传输层(TCP,UDP)

4.TCP与UDP

  • TCP特点: 传输可靠—保证顺序(滑动窗口),
    不丢包(重传机制RDT),有拥塞控制
    三次握手,建立链接
    数据包没有限制
    可以依靠网络层去分帧
  • UDP特点:
    传输不可靠—不保证顺序,可能丢包,
    实现机制比较简单
    无连接,随时发送
    UDP协议一般要求包小于64K

5.关于TCP与UDP的选择
二者在不同的游戏里面都有广泛的应用,没有绝对好坏之分。TCP相比UDP数据安全可靠,但是需要建立链接,机制复杂带来额外的开销,在网络环境不好的情况下效果非常差。
TCP应用场景:网络条件较好,对安全可靠性有要求的
UDP应用场景:网络环境较差,要求响应速度比较高,安全性其次的

6.进程通信
在同一个机器上,两个不同的进程之间有多种通信方式。如管道,消息队列,信号量
,信号,共享内存等。(这属于操作系统基础知识)
如果想在两个不同机器的进程之间通信,就需要用到Socket套接字。(当然他也可以用于同一个机器不同进程通信)

7.socket
从宏观概念上理解,socket是一套基于TCP/IP协议封装的API。他处于网络应用层,给开发者提供方便的接口来快速的实现网络通信。网上有的朋友把他比喻成插座,处于两个机器上的两个进程想要通信,就需要各自创建一个插座,然后把自己插在这个插座上,这样你只要把信息通过这个插座传输过去就好了而不需要管插座里面有什么特殊的机制与技巧。当然,理论上你不用插座直接用手把线路焊接到一起也是没问题的,不过里面的电流过大断电机制什么的需要你自己想办法处理了。
从编程的角度来讲,socket是一个无符号整型变量,用来标识一个通信进程。两个进程想要通信必须要知道双方的ip地址和端口号,以及通信所采用的协议栈。socket就是和这些东西绑定的,socket编程可以使用unix接口,也可以使用windows的接口winSock。
参考链接:
socket编程到底是什么?(https://www.zhihu.com/question/29637351/answer/67610424
谈谈socket 套接字(http://blog.csdn.net/farsight2009/article/details/53540546
TCP/IP、Http、Socket的区别? http://www.zhihu.com/question/39541968?utm_source=qq&utm_medium=social

7.游戏开发中的基本网络架构
理解了socket之后,所谓游戏中的网络框架也不难理解。其实就是在socket的基础上进一步封装一套更方便游戏内部的消息传输机制,同时将消息解析细节与逻辑层代码进行分离,使逻辑层代码更清晰可读。低配版:比如客户端想给服务器发送一个比较复杂的数据结构(比如一个包含字符串和数字的结构体),那这个数据需要在客户端转换成二进制,通过socket发送到服务器。服务器的网络机制通过其socket监听到该数据包,然后解析二进制数据并还原到逻辑上层。
高配版:只简单的发送与解析一般数据还不够,游戏中我们希望直接能将一个对象直接从客户端发到服务器,或者直接将某个函数发到服务器去执行,更甚者想要在逻辑层实现UDP的可靠数据传输。这些较为复杂的机制都包含在网络框架里面,有时候我们可以借用一些开源的库来帮我们实现,如protobuf。

8.protobuf
Google Protocol Buffer(Protobuf)是一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,通常用于通讯协议和数据存储等领域。通俗一点讲,就是用来按照二进制格式保存与读取的开源库,我们在进行网络传输的时候需要把数据转换成二进制通过网络层发送过去,但是如何把复杂数据(一个类对象)准确地转换成二进制发送并在接收端快速准确解析就是个问题。protobuf就可以做这个工作,他可以把一个对象序列化成二进制,然后在接收端再反序列化成原来的对象内容,这样我们就成功的传输了一个类对象!
这个过程我们是在应用层来实现的,所以本质上游戏网络层的实现对应的就是计算机网络模型中的应用层(和Http,ftp是类似的)

9.GUID
该课程中没有涉及,但是有必要提出来。前面提到我们可以在网络中传递一个对象,但是客户端上的A对象(如玩家A)与服务器上的A对象(也是玩家A)在内存地址上肯定是不一样的,我们怎么知道客户端传递过来的A对象就是服务器上的?
答案就是GUID,服务器在同步一个对象引用(指针)的时候,会给其分配专门的GUID并通过网络进行发送。客户端上通过识别这个ID,就可以找到对应的类对象。具体的细节可以参考虚幻引擎里面的实现机制,博主也写了一篇文档,里面有提到该机制的相关细节http://blog.csdn.net/u012999985/article/details/78384199

10.事件与代理
游戏中常用的模块之间通信方式,可以极大的降低模块耦合性。实现原理是函数指针,比如A模块执行了某个操作后,通过广播向所有模块发消息,这些模块如果事先绑定了对应消息的函数指针,就会收到该消息并处理。这个过程中A并不知道发给了谁,也不知道其他模块又做了什么。


上一篇:游戏开发入门(九)游戏网络同步
下一篇:游戏开发入门(十一)游戏引擎架构

原文链接(转载请标明):http://blog.csdn.net/u012999985/article/details/79357430

没有更多推荐了,返回首页