网络服务器软件开发/中间件开发,关注ACE/ICE/boost

C++博客 首页 新随笔 联系 聚合 管理
  152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks

          四.结构体(message)

ProtobufMessage结构是由一系列的key-value对组成的。其中,key由两部分组成,成员序号field_numbervalue的类型wire_type,他们通过(field_number << 3) | wire_type的方式编码为一个varintvalue根据wire_type而定;

         Message结构由.proto文件定义,这是协议双方的接口文件,文件里面定义了每个结构成员的序号即field_number,以及每个成员的类型(该类型会映射到wire_type),例如:

message MSG_Login_Rsp

 {

                required 1:uint32 rspcode = 100;//返回值,1为默认值

                required 2:string rspdesc = "success"; //success为默认值

}

     其中,rspcode的序号为1,类型为uint32,默认值为100rspdesc的序号为2,类型为string,默认值为success

     下面我们来看如何根据proto文件序列化结构体(proto文件的规则后续的文章中会说明,这里只是原理性的描述)。

     首先,需要做成员类型的划分,如下:

                                 

Type

含义

使用场景

0

Varint

uint8,uint16,uint32

2

Length-delimited

String ,bytesembedded messages,repeated fields

        说明1)embedded message为结构体的嵌套类型

               2)repeated fields为某个可能重复的字段,重复次数可以为0

                   3Length-delimited的含义是“长度+值”,其中长度采用varint编码,值为字符序列或者二进制码流

                   4Type的含义就是前文提到的wire_type

            1)uint32为例,假若有如下proto接口

                     message Test1

                     {

                            required 1: uint32 a = 150;

                     }

    查看序列化的结果,可以得到16进制:

08 96 01

    由于uint32类型较为简单,我们容易得出,key8,其中wire_type0field_number1value150

             2)以string字符串为例,假若有如下proto接口

                     message Test2

                     {

                            required 2: string msg = “testing”;

                     }

    此时如果序列化,我们回得到下面16进制码流:

                     12 07 74 65 73 74 69 6e 67

    刚才已经提到message的编码都是key-value对,OK,我们对号入座,由于key是一个varint,我们很容易断定12就是key,将12转化为二进制格式:0001 0010,得出:wire_type2field_number2,说明接下来会出现Length-delimited类型,根据“长度+值”的规则,推断出7string的长度,string为“testing”。

            3)以结构体的嵌套(embedded message)为例,假若有如下proto接口

                     message  Test3

                     {

                            required 3: Test1;

                     }

    看序列化码流:

                     1a 03 08 96 01

    参考上面string的情况,我们得到:key1a,其中wire_type2field_number3value的为 08 96 01,注意此时value本身是一个key-value对,这个对我们在1)中已经做了解析。

     

      下一篇文章会描述proto接口文件的规则(主要基于libprotobuf的规则,但又有简化)

 

   

posted on 2009-09-11 19:35 true 阅读(1818) 评论(0)  编辑 收藏 引用 所属分类: 网络服务器开发编码知识通信技术

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理