protocol buffers c++(protocol-buffer 消息的格式)
本文目录
protocol-buffer 消息的格式
本文用来介绍Google的protocol-buffer 消息的格式以及使用事项,不会涉及相关api的使用
消息由至少一个字段组合而成,类似于C语言中的结构。每个字段都有一定的格式 字段格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ |
限定修饰符包含 required optional repeated
protocol-buffer 基本数据类型
补充说明 N 表示打包的字节并不是固定。而是根据数据的大小或者长度。例如int32,如果数值比较小,在0~127时,使用一个字节打包。关于枚举的打包方式和uint32相同。关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.
有关enum message 特说说明
在定义message类型的时候,也许会有这样一种需求:其中的一个字段仅需要包含预定义的若干个值即可。比如,对于每一个搜索请求,现需要增加一个分类字段,分类包含:UNIVERSAL, WEB, IMAGES, LOCAL, NEWS, PRODUCTS or VIDEO。要实现该功能,仅需要增加一个枚举类型字段。如下:
可以定义枚举在一个message内部,也可以定义在message的外部,这样的枚举可以被其他任何.proto文件内的message复用。
使用其他Message类型作为filed类型 PB允许使用message类型作为filed类型。例如,在搜索相应message中,包含一个结果message。此时,只需要定义一个结果message,然后再.proto文件中,在搜索结果message中新增一个字段,该字段的类型设置为结果message即可。
在上例中,Result message类型与SearchResponse 定义在同一个文件中,假如有这么一种情况,这里所要使用的Resultmessage已经在其他的.proto文件中定义了呢? 可以通过导入其他.proto文件来使用其内的定义。为达此目的,需要在现.proto文件前增加一条import语句:
嵌套类型: Message类型可以嵌套,类似于c++中的嵌套类,可以无限深层次嵌套。
protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.
有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。 编码值的取值范围为 1~2^32(4294967296)。 其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16. 1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。 protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。 消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。 建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。
protocol-buffer 允许设置可选字段(optional)。顾名思义,在一条message中,该字段可设值也可不设。假如没有设置,那么在解析该字段的时候,会根据该字段类型,给其赋一个类型默认值。除此之外,也可以在定义message格式的时候,就为optional字段设置一个默认值,如下:
假如没有赋值的话,会被赋上默认值。对于简单类型,默认值可以自己设定,例如上例的PhoneNumber中的PhoneType字段。如果没有自行设定,会被赋上一个系统默认值,数字类型会被赋为0,String类型会被赋为空字符串,bool类型会被赋为false。对于枚举类型,默认值是枚举列表中第一个值
本文将网上的一些资料进行整理,汇成此文,记录下自己学习的历程 主要的参考资料:***隐藏网址***
protocol buffer能在php用吗
要使用之前先到code.google.com上搜索protocol buffer,下载到本地,解压后依次执行:./configuremakemake checkmake install最后一步涉及到权限,可能会需要sudo。二、定义一个proto文件下面依然是给出一个简单的例子,要使用proto首先需要自己定义一个proto文件,定义一个people.proto文件,内容如下:message people{optional string name = 1;optional int32 height = 2;}三、生成一个python可用的py文件然后就是生成对应的py文件,命令如下:protoc -I=./ --python_out=./ people.proto其中-I是source的路径,--python_out表示对应python库的生成路径,然后是对应的proto文件。当然,pb还支持c++和java,修改--python_out即可。完成后就有对应的people_pb2.py文件了。导入后即可使用,第一次安装后直接用应该会提示:ImportError: No module named google.protobuf,这是因为找不到对应的库路径导致,到你下载的pb路径下,找到python路径,执行sudo python setup.py install,执行完后可以通过执行sudo python setup.py test检查是否有安装成功,如果最后提示----------------------------------------------------------------------Ran 193 tests in 0.327sOK那么就是安装成功了,此时再导入对应的pb2.py文件即可使用。四、导入使用的简单例子给出一个简单的调试例子:import people_pb2pbFirstPeople = people_pb2.people()pbFirstPeople.name = joeypbFirstPeople.height = 160print pbFirstPeople输出结果为:name: joey
googlec++主要用什么编译器
Bazel和protocolbuffers。1、Bazel,是一个开源的、支持多种语言、跨平台、跟Make相似的编译工具。2、protocolbuffers,是Google提供的跨语言编译器,只需要用它进行编译,可以编译成Java、python、C++等代码。
protocol buffer的service接口生成问题
什么是protocol bufferProtocolBuffer是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。1.2 他们如何工作你首先需要在一个 .proto 文件中定义你需要做串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。这里有个非常简单的 .proto 文件定义了个人信息:message Person { required string name=1; required int32 id=2; optional string email=3; enum PhoneType { MOBILE=0; HOME=1; WORK=2; } message PhoneNumber { required string number=1; optional PhoneType type=2 ; } repeated PhoneNumber phone=4;}有如你所见,消息格式很简单,每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级。你可以指定可选字段,必选字段和重复字段。你可以在( gle.com/apis/protocolbuffers/docs/proto.html )找到更多关于如何编写 .proto 文件的信息。一旦你定义了自己的报文格式(message),你就可以运行ProtocolBuffer编译器,将你的 .proto 文件编译成特定语言的类。这些类提供了简单的方法访问每个字段(像是 query() 和 set_query() ),像是访问类的方法一样将结构串行化或反串行化。例如你可以选择C++语言,运行编译如上的协议文件生成类叫做 Person 。随后你就可以在应用中使用这个类来串行化的读取报文信息。你可以这么写代码:Person person;person.set_name("John Doe");person.set_id(1234);person.set_email("jdoe@example.com");fstream.output("myfile",ios::out | ios::binary);person.SerializeToOstream(&output);然后,你可以读取报文中的数据:fstream input("myfile",ios::in | ios:binary);Person person;person.ParseFromIstream(&input);cout 《《 "Name: " 《《 person.name() 《《 endl;cout 《《 "E-mail: " 《《 person.email() 《《 endl;你可以在不影响向后兼容的情况下随意给数据结构增加字段,旧有的数据会忽略新的字段。所以如果使用ProtocolBuffer作为通信协议,你可以无须担心破坏现有代码的情况下扩展协议。你可以在API参考( oogle.com/apis/protocolbuffers/docs/reference/overview.html )中找到完整的参考,而关于ProtocolBuffer的报文格式编码则可以在( .google.com/apis/protocolbuffers/docs/encoding.html )中找到。1.3 为什么不用XML?ProtocolBuffer拥有多项比XML更高级的串行化结构数据的特性,ProtocolBuffer:更简单小3-10倍快20-100倍更少的歧义可以方便的生成数据存取类例如,让我们看看如何在XML中建模Person的name和email字段:《person》 《name》John Doe《/name》 《email》jdoe@example.com《/email》《/person》对应的ProtocolBuffer报文则如下:#ProtocolBuffer的文本表示#这不是正常时使用的二进制数据person { name: "John Doe" email: "jdoe@example.com"}当这个报文编码到ProtocolBuffer的二进制格式( .google.com/apis/protocolbuffers/docs/encoding.html )时(上面的文本仅用于调试和),它只需要28字节和100-200ns的解析时间。而XML的版本需要69字节(除去空白)和 5000-10000ns的解析时间。当然,操作ProtocolBuffer也很简单:cout 《《 "Name: " 《《 person.name() 《《 endl;cout 《《 "E-mail: " 《《 person.email() 《《 endl;而XML的你需要:cout 《《 "Name: " 《《 person.getElementsByTagName("name")-》item(0)-》innerText() 《《 endl;cout 《《 "E-mail: " 《《 person.getElementsByTagName("email")-》item(0)-》innerText() 《《 end;当然,ProtocolBuffer并不是在任何时候都比XML更合适,例如ProtocolBuffer无法对一个基于标记文本的文档建模,因为你根本没法方便的在文本中插入结构。另外,XML是便于人类阅读和的,而ProtocolBuffer则不是。还有XML是自解释的,而 ProtocolBuffer仅在你拥有报文格式定义的 .proto 文件时才有意义。1.4 听起来像是为我的解决方案,如何开始?下 er编译器,用于生成你需要的IO类。构建和安装你的编译器,跟随README的指令就可以做到。一旦你安装好了,就可以跟着编程指导( ogle.com/apis/protocolbuffers/docs/tutorials.html )来选择语言-随后就是使用ProtocolBuffer创建一个简单的应用了。1.5 一点历史ProtocolBuffer最初是在Google开发的,用以解决索引服务器的请求、响应协议。在使用ProtocolBuffer之前,有一种格式用以处理请求和响应数据的编码和解码,并且支持多种版本的协议。而这最终导致了丑陋的代码,有如:if (version==3) { ...}else if (version》4) { if (version==5) { ... } ...}通信协议因此变得越来越复杂,因为开发者必须确保,发出请求的人和接受请求的人必须同时兼容,并且在一方开始使用新协议时,另外一方也要可以接受。ProtocolBuffer设计用于解决这一类问题:很方便引入新字段,而中间服务器可以忽略这些字段,直接传递过去而无需理解所有的字段。格式可以自描述,并且可以在多种语言中使用(C++、Java等)然而用户仍然需要手写解析代码。随着系统的演化,他需要一些其他的功能:自动生成编码和解码代码,而无需自己编写解析器。除了用于简短的RPC(Remote Procedure Call)请求,人们使用ProtocolBuffer来做数据存储格式(例如BitTable)。RPC服务器接口可以作为 .proto 文件来描述,而通过ProtocolBuffer的编译器生成存根(stub)类供用户实现服务器接口。ProtocolBuffer现在已经是Google的混合语言数据标准了,现在已经正在使用的有超过48,162种报文格式定义和超过 12,183个 .proto 文件。他们用于RPC系统和持续数据存储系统。2 语言指导本指导描述了如何使用ProtocolBuffer语言来定义结构化数据类型,包括 .proto 文件的语法和如何生成存取类。这是一份指导手册,一步步的例子使用文档中的多种功能,查看入门指导( m/apis/protocolbuffers/docs/tutorials.html )选择你的语言。2.1 定义一个消息类型@waiting …2.2 值类型@waiting …2.3 可选字段与缺省值@waiting …2.4 枚举@waiting …2.5 使用其他消息类型@waiting …2.6 嵌套类型@waiting …2.7 更新一个数据类型@waiting …2.8 扩展@waiting …2.9 包@waiting …2.10 定义服务@waiting …2.11 选项@waiting …2.12 生成你的类@waiting …3 代码风格指导本文档提供了 .proto 文件的代码风格指导。按照惯例,你将会,你将会生成一些便于阅读和一致的ProtocolBuffer定义文件。3.1 消息与字段名使用骆驼风格的大小写命名,即单词首字母大写,来做消息名。使用GNU的全部小写,使用下划线分隔的方式定义字段名:message SongServerRequest { required string song_name=1;}使用这种命名方式得到的名字如下:C++: const string& song_name() {...} void set_song_name(const string& x) {...}Java: public String getSongName() {...} public Builder setSongName(String v) {...}3.2 枚举使用骆驼风格做枚举名,而用全部大写做值的名字:enum Foo { FIRST_VALUE=1; SECOND_VALUE=2;}每个枚举值最后以分号结尾,而不是逗号。3.3 服务如果你的 .proto 文件定义了RPC服务,你可以使用骆驼风格:service FooService { rpc GetSomething(FooRequest) returns (FooResponse);}4 编码本文档描述了ProtocolBuffer的串行化二进制数据格式定义。你如果仅仅是在应用中使用ProtocolBuffer,并不需要知道这些,但是这些会对你定义高效的格式有所帮助。4.1 一个简单的消息@waiting …4.2 基于128的Varints@waiting …4.3 消息结构@waiting …4.4 更多的值类型@waiting …4.5 内嵌消息@waiting …4.6 可选的和重复的元素@waiting …4.7 字段顺序@waiting …5 ProtocolBuffer基础:C++@waiting …6 ProtocolBuffer基础:Java@waiting …7
更多文章:
我家以前迅雷速度达150~220现在怎么只有二三十了?p2psvc与p2pimsvc是什么
2024年7月15日 06:41
果儿、尖果、苍果、戏果分别是什么意思(老北京话)?带尖的水果有哪些
2024年3月15日 20:40
24个形状图片,4个图形一组,第24个是什么图形?立方体拼图注册商标属于哪一类
2024年6月23日 04:53
花粉俱乐部账号怎么看?华为花粉俱乐部停止运营,已运营10年之久,为何会突然关闭
2024年7月6日 14:04
5173游戏交易平台官网电脑版网页(5713网游交易平台网址多少急需)
2024年6月20日 06:04