游戏开发—协议设计

协议就是通信双方能够理解的一种数据格式。维基百科这么定义网络协议:

网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。

协议设计包含三要素:

语法:语法是用户数据与控制信息的结构与格式,以及数据出现的顺序。

语义:解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。

时序:时序是对事件发生顺序的详细说明

也就是说,语义表示要做什么,语法表示要怎么做,时序表示做的顺序。我们要基于此来设计我的协议。

通常游戏有一些特殊性,比如流量要尽量的少,安全性要求更高,以及对平台支持足够多等等。这一切的需求就要求游戏协议设计,尽量简单、通用,以及代码层上易扩展、解析效率足够高等特点。

基于此,我需要从以下几个层次来考虑游戏协议的设计方案。

知识图谱

因为知识点比较多,建议先读知识图谱,对整体结构有一个清晰的综括。


协议三个层次

应用层

应用层主要是常用是解析方式定义和解析,主要的选型,主要是看你基于什么需求了,适用于实际需求就好。我们常用的协议类型,主要有这两种:文本协议、二进制协议

1、文本协议:

文本协议设计的目的就是方便人们理解,读懂。如常见的http协议,一般的常见http协议如下:

这种格式非常贴近我们的文字描述,方便阅读,而且目前HTTP也是客户端浏览器或其他程序与Web服务器之间的应用层通信协议,适用非常广泛。

但你也看到,有时候基于一个很简单应答,就要带上很多其他的头信息,这对于对流量有要求的游戏应用来说,还是很浪费的。

优点

1、通用,适用广泛

2、方便理解,可读性好

缺点:

1、基于行读,解析效率一般

2、携带附带信息过多,传输的效率低下

3、无状态,服务器不知道客户端的状态,必须基于客户端的请求来回应,实时性低

4、很难嵌入其他数据,对二进制支持差

如果你的游戏对实时性要求不高,而且对流量要求不也是太高,文本协议也是个不错的方式。一般短连接游戏多适用这个。

2、二进制协议

二进制协议就是一串字节流,是一个典型的Ip协议,一般通常包括消息头(header)和变长的消息体(body),消息头的长度固定,消息体长度不固定,包含主要的内容主体。一般消息头会包含消息体的长度,这样就能基于头信息从数据流中解析出一个完整的二机制消息了。

一般的格式如下:

我们看到head部分定义包含:

cmd:命令字

sign:验证串

content-leg:消息体长度

HeaderCRC:头验证(不是必须)

其中命令字是双方协议文档中规定好的,比如0x01表示登陆,0x02表示注册等等,这些就是一个命令号。

sign是一个验证字符串,对消息体数据进行一定加密验证,保证数据安全。

content-leg是本次消息体的长度。


body部分,比如我们如下定义:

message:login{

string username;

int64 passwoard;

}

我们看到,因为字段的数据类型有定义,顺序也有定义(第一个是string,第二个是int64),整个二进制流读取的的时候,基于顺序读取就可以很快的取出了。

优点

1、没有冗余字段,传输高效,耗费流量小

2、解析速度快,基于基础数据类型操作

缺点:

1、可读性差,不利于调试

2、扩展性差,对复杂数据结构支持不够

如果你的游戏,对实时性要求比较高,流量有要求,用二进制比较好,一般大型多人网游,使用二进制协议来设计。

3、数据格式

以上我们看到了两种协议类型,但对于消息体的解析介绍很少,消息体的格式决定了的他的语义和时序,格式不同数据的序列化和反序列化也是不同。比如message:login,你可以基于json来定义,也可以基于xml来定义,定义不同解析方式也各不相同。

一般的消息体数据格式主要有以下几种:json、protocolBuff、xml、自定义

json

json是一种轻量级的数据交换格式,互联网应用的很广泛了。常用的框架也很多,推荐fastJson,解析速度还是不错的。json的好处是,开源,格式统一,解析速度也还可以。缺点就是会有一些冗余字符,不够简洁。

protocolBuff

protocolBuff是是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言。但是比这些占用空间都小,没有冗余字段。而且好处是灵活,解析速度快,易于开发(基于配置自动生成代码),可支持语言也比较多。一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一

xml

不多解释了,大家都用有过,强烈不建议使用这种,除了无效字符过多(标签),而且解析效率比上面两种都是很低的。

自定义

自己定义就是自己定义解析方式,比如通过文档定义好一个消息的结构,第一个字段是什么类型,第二个字段什么类型...等等,基于此自己写工具解析。好处是对外协议不透明,解析效率和传送效率都还不错,缺点就是开发难度高,不容易维护。

各种格式优缺点如下:

安全层

游戏通信,安全也很重要,不然协议被破解,用户刷资源,整个游戏的平衡性就被破坏了,轻者影响其他玩家体验,重则游戏直接被废。

一般的安全处理就是对协议进行加密。一般有以下几种:

1、常规加密

采用对称加密或者hash加密来对消息内容进行加密,两端采用同一种加密算法,基于同一个密钥对消息体进行加密换算,以此来查看数据是否一致。

密钥可以用户登陆的时候获取一次。还有一种是基于每个用户密钥不同,以此防止密钥泄露大范围影响全服玩家。

2、动态加密

动态加密,可以提前设置一个私有密钥库,里面包含一定数量的密钥,每次客户端请求的时候,基于协议号来设计一个算法获取其中一个密钥。每个协议的密钥都是在协议到达的时候时时获取的,这样即便某一个协议的密钥被破解,对其他协议依然无效。

3、其他

采用非对称加密,或者加盐处理。这个不详讲了,非对称加密速度太慢了,不建议。

传送层

考虑服务端的承载成本,以及手机上游戏网络环境差,原则上UDP是比TCP更适合的方式。但是由于游戏对于数据完整性、安全性要求比较高,采用TCP的又可靠与安全。

目前采用netty作为推送服务器的也有支持上百万连接的应用了,tcp这块性能对于一般游戏支持足够了。长链接游戏多采用分区分服来应对高并发压力,短链接多采用分布式来应对。

一些问题

1、字节序

二进制协议中,字节序需要注意,跨语言、平台通信的时候会出现乱码问题。目前的字节序主要有,Little endian和Big endian之分,也就是常说的大头和小头之分。

具体是大头在前还是小头在前,这个和主机的cpu有关系PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。这个在手机主机上也会出现。

应对方案是:

客户端和服务端强制采用一种字节序,一般采用网络字节序(big endian)

2、浮点数

协议中出现浮点类型要特别注意,浮点类型的传送上面字节序处理OK了,还得注意浮点数的多平台运算不一致问题。

比如游戏中要对寻路、战斗等公式计算,牵扯到浮点数了,有可能前后端算出的不一致,以Arm为例,Arm的浮点数就有软模拟、硬件IEEE-754兼容、SIMD下IEEE-754不兼容三种情况。

应对方案是:

1、统一一种格式,比如前后端都采用软模拟,或者强制采用硬件IEEE-754(软模拟速度慢)

2、转换为定点数,也就是浮点转换为整数(速度快)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容