喜糖

移动开发工程师 。涉及 android、ios、jni

导航

通讯协议的理解学习

Posted on 2011-06-07 11:49  喜糖  阅读(2100)  评论(0编辑  收藏  举报

1 前言

提到通信就得面临两个问题,一是通信协议的选择,二是数据协议的定义。通信协议耳熟能详的就有好几种,TCP,UDP,HTTP,FTP等等。数据协议是一种数据交换的格式,像jason,xml,amf3,google protocol都可以用作数据协议,也可以自己根据通信的效率,安全等因素来定义自己的数据协议。

如果想开发一个比较出色/健壮的通讯协议,就需要从几个方面进行着手。

一、通讯粘包的处理;

二、数据协议选择;

三、网络安全性和压缩;

2 协议的关注度介绍

2.1 通讯粘包的处理

这里包的概念是逻辑上的数据包,也就是我们发送的一个完整业务消息包,粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。

为了避免粘包现象,可采取以下几种措施。一是对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令 push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;二是对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;三是由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。

以上提到的三种措施,都有其不足之处。总的来说降低了通信系统的吞吐量。我们可以自己设计一个分包算法来处理粘包的问题,该算法的实现是这样的:

1. 当有数据到达时,将数据压入程序缓冲区。

2. 循环处理缓冲区,如果缓冲区长度大于包头长度,则取出长度信息n,否则跳出循环,如果缓冲区的长度大于n,则从缓冲区取出一个完整包进行处理,否则跳出循环.比如钢铁中的GameDecoder就是这个样子的。

2.2 通讯协议的选择

现在已经有很多数据协议可供我们选择,像json,xml,google protocol等等,这些协议相应的语言都有API来对自身数据做协议处理,我们选择协标准无非就是效率和大小。主要分为这么几种类型:

一、url参数型,如:a=xxx&b=yyy

二、xml格式,如<value><a>xxx</a><b>yyy</b></value>

三、json格式,如a:xxx;b:yyy

四、纯文本格式,如a=xxx b=yyy\r\n

五、自定义二进制格式。如【消息长度】【消息类型】【A参数】【B参数】

六、其他一些格式。比如google protocol,amf3.0等

2.3 网络安全性和压缩

在使用协议时还要注意到协议的安全性,要能进行加/解密。最好还能进行一下压缩。

3项目的协议分析

格式: 【消息长度(2字节)】【消息类型(2字节)】【消息内容】【\0结束】。前两个字节来表示消息的长度,后面两个字节由来表示消息的类型。后面的内容就是消息的主体内容了。

在消息内容中会涉及到一些复杂的数据结构。屠魔中采用了PropertyBag的形式来表达,而钢铁中采用了Json的方式来表达。但他们的核心思想都是使用Key-value的形式来表示。方式不同的原因是钢铁采用Flash的客户端,可以非常方便的解析json串,方便了游戏的开发。