【高效server实践】--协议先行

网络协议是为计算机程序之间进行数据交互的规则和标准,在正式写server之前应该先定好协议,方便C/S两端同时开发良。好的协议应该体量小,封包解包快,良好的扩展性,不可直接读,跨语言,跨平台。
目前流行的几种网络协议对比如下:
1: json是应用较为普遍的协议,它支持键值,数组,嵌套,满足各种数据传输需求。有良好的可读性(有些程序数据的私密性可能不希望有可读性),:跨平台跨语言。但是json的封包解包慢,数据包相对较大,而且因为其可读性给数据私密性带来了风险。
2: 定长结构体和字节拼凑法的封包解包效率最高,字节拼凑法包体最小紧凑无冗余内容,定长结构体由于其定长会造成空间利用不充分。由于定长结构和字节拼凑的规则约束,跨平台和跨语言的支持不好,开发调试也不便。协议一旦扩展升级,就要对所有的c/s端进行升级。字节拼凑法具体实现过程是:
例如一个完成TCP包包括包头和包体:定义前8个字节为头部(4个字节代表TCP包序列号,4个字节代表包长),包体按一定的序列组织在一起,如一个请求登录的包 体为:账户ID+账户密码,则相应的包体则为:前4个字节存账户ID+4个字节存账户密码长度+账户密码。
3:protocolbuffer是google的一种数据交换格式,它跨语言跨平台,把数据序列化成二进制的格式,比json协议数据量小且封包解包速度更快。protocolbuffer由google开源,已经对三语言:java,c++和pyhon都实现了编译器和库文件,开发者只要按照一定的规则定义数据对象,即可通过现成人编译器快捷地生成协议源文件在异构系统中使用。protocolbuffer支持多种值类型:整型,字符串,浮点型,字节,嵌套。protocolbuffer支持三种字段类型:required,optional,repeated,协议扩展性好,只要遵守以下规则就可以让新老协议在新老程序中同时运行
1:不要修改已经存在字段的标签号
2:任务新添加的字段必须是optional或repeated限定符号
3:不能移除在原有协议中存在的required字端
protocolbuffer的序列化原理可以详见:http://blog.csdn.net/wwwangcai/article/details/44746569,其核心算法是Varint(一种紧凑数字表示方法,它用一个或多个字 节表示一个数据,值越小的数字字节越少),对于int,bool,enum使用varint,对于string,bytes,messge等类型,value就是长度+原始内容。使用以上方法封包,字节 紧凑,包体更小。包体内容可以流式解析,解包更快。
4:Thritf TProtocol是facebook广泛使用的类似protocolbuffer的一种跨语言跨平台的二进制(也可选择字符串)通信协议,开发者也得按照一定的规则定义数据对象,通过不同的编译器快捷地生成协议源文件在异构系统中使用,它支持的语言更多:c++,python,java,ruby,perl,php,c#等。但它更多是Thrift RPC机制里的一部分,不能独立使用,学习成本更高。Thritf TProtocol的包解包速度慢于protocolbuffer,同样的结构体压缩后的二进制数据大小与protocolbuffer的相近。

5:另有一种基于TLV(tag len value)方法的二进制协议PDU,它支持多语言,多平台,封包解包效率良好,扩展性好,能够随时增删协议字段,且与字段的位置无关。它也需要按一定的规则定义数据对象(每一个pdu对象内的tag字段都是唯一的):

【高效server实践】--协议先行_第1张图片

根据TLV方法(Tag:固定长度,2字节,内容是xml描述文件中的tag字段值,Len:固定长度,2字节,内容是value的实际字节长度 ,Value:具体长度由len指定,内容是待传输的值 )封装出来的字节结构出下:

【高效server实践】--协议先行_第2张图片


 
 

你可能感兴趣的:(二进制协议,protocolbuf,字节拼凑,跨语言,跨平台)