游戏之网络初篇

说教无益,折断的骨头是最好的课本 --俄洛伊

选择哪种协议作为游戏的通信协议对一款网游来说至关重要,因为根据游戏的分类,不同类型的游戏往往都有与之相匹配的协议来满足玩家的体验,因此,在选择通信协议时,要立足游戏的玩法类型,并预估本游戏的消息频率和对延迟的容忍度选择最合适的协议。通常,游戏可供选择的协议有TCP,UDP,HTTP,WebSocket。其中TCP是大多数角色扮演类网游采用的协议,如魔兽世界等;UDP是大多数竞技类游戏采用的协议,如英雄联盟,王者荣耀,穿越火线等;HTTP基本上是一些网页游戏采用的协议;WebSocket基本上是微信小程序游戏(或H5页游)采用的协议。

说到网络,不得不提两大著名的网络通信模型,一为OSI参考模型,由国际标准化组织提出,一个试图使各种计算机在世界范围内互连为网络的标准框架;一为TCP/IP四层模型(链路层,网络层,传输层,应用层),由美国国防部开发提出,因OSI的七层模型在实际应用中开销极大,不说别的,光这7层就老在面试中遗漏,记都难记,而TCP/IP则因其简洁实用低成本且开放特性已成为事实上的首选协议。上面提到的TCP,UDP协议就是传输层所使用的协议;HTTP,WebSocket则是应用层所使用的协议。其中,HTTP是一种基于TCP的协议(需要利用TCP建立连接),而WebSocket协议又是基于HTTP协议的,可以说是HTTP协议的升级版,因为HTTP协议是一种半双工的协议,仅能实现单向通信,即同一时刻,仅能由客户端发起请求,服务端再返回数据,传统的采用HTTP协议的网页游戏通常采用客户端“轮询”的方式(啰嗦且协议头长),实现客户端和服务端的假双向通信。但是,WebSocket却是真双向通信(全双工),它通过在HTTP协议里增加
Upgrade: websocket
Connection: Upgrade
告知服务器协议需升级为WebSocket(服务端需先支持WebSocket协议),升级后即可实现双向通信,这样,游戏服务器在有需要的时候可以主动传数据给客户端,而不需要客户端自己来问。

注意,上面的HTTP协议和TCP协议里还有个细节的注意点,就是它们都有个Keep alive的概念,很多人容易把这两个概念混淆,这里简单说下它们的区别。HTTP 的Keep-Alive是在HTTP1.1默认使用的,它引入的意图是让TCP连接复用(就是连接保持一段时间),而TCP的Keepalive机制的意图在于探测连接的对端是否还存活。

从上可知,TCP,UDP协议是最基本的两种协议,相信很多人已知它们有如下的区别:

tcp与udp区别.png

通常,还需知道TCP的经典面试题之建立连接三次握手过程,断开连接四次挥手过程,这里就不再百度粘贴了。了解即可。

最后,做游戏一定要知道TCP的粘包拆包问题,这在现在的通信框架Netty、Mina中都有处理,现在很多游戏都用这两个框架,尤其是Netty。
引用李林锋大神《Netty权威指南》中的话:

Tcp是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,它们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体定义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

TCP粘包拆包发生的原因(摘录网上烂大街的原话,结合李林锋大神的书里解释,我觉得还是网上的要通俗得多):
1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。
2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。
3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。
4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。

粘包问题的解决策略(李林锋):

由于底层的TCP无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,可以归纳如下。
1)消息定长。例如每个报文的大小为固定长度200字节,如果不够,空位补空格;
2)在包尾增加回车换行符进行分割,例如FTP协议;
3)将消息分为消息头和消息体,消息头中包含消息总长度(或者消息体长度)的字段,通常设计思路为消息头的第一个字段使用int32来表示消息的总长度;
4)更复杂的应用层协议。

游戏中粘包的解决策略通常采用的是第三点,这将在后面的系列博文《使用Netty+Protobuf实现游戏TCP通信》和《使用Netty+Protobuf实现游戏WebSocket通信》中将有体现,欢迎阅读。

你可能感兴趣的:(游戏之网络初篇)