前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Protobuf协议?盘他!

Protobuf协议?盘他!

原创
作者头像
audy
发布2019-04-28 17:23:01
1.4K0
发布2019-04-28 17:23:01
举报
文章被收录于专栏:游戏测试开发游戏测试开发

一、Protobuf是什么鬼?

Protobuf是Google基于C++ 进行的实现的一套数据序列化/反序列化库,开发人员可以根据 ProtoBuf 的语言规范生成多种编程语言(C++、Python、Java 等)的接口代码。使用ProtoBuf的文件在存储效率上和处理性能上都元高于XML,也具有更好的跨平台性,使用灵活。

二、Protobuf要怎么用?

Step1、根据需求写proto文件

proto文件即消息协议原型定义文件,在该文件中我们可以通过使用描述性语言,来定义程序中需要用到数据格式。首先Google给了一个电话簿的proto例子。

代码语言:javascript
复制
message Person {
  requiredstring name = 1;
  requiredint32 id = 2;
  optionalstring email = 3;
  messagePhoneNumber {
    requiredstring number = 1;
    optionalPhoneType type = 2 [default = HOME];
  }
  repeatedPhoneNumber phone = 4;
}
message AddressBook {
  repeatedPerson person = 1;
}

一个Message是一个包含一组类型字段的集合。包括bool,int32,float,double和string或者自己定义的结构来定义一个Message。每一个类型字段前面必须要有一个修饰符包括:required、optional、repeated。

1)required字段的初值是必须要提供的,否则该字段会被认为“未初始化的”,在序列化和反序列化的时候会报错!所以,对于修饰符为required的字段,务必进行初始化赋值。

2)对于optional的字段而言,如果未进行初始化,那么会有默认值赋值该字段,如上述proto定义中的email 和PhoneType字段类型。

3)对于repeated的字段而言,该字段可以重复多个,上述的AddressBook例子便有个很好的该修饰符的应用场景,即每个人可能有多个电话号码。而在proto定义文件中可以使用repeated来修饰的字段类型,类似于一个数组,他可以包含多个数值。

其中字段标签标示了字段在二进制流中存放的位置,这个是必须的,而且序列化与反序列化的时候相同的字段的Tag值必须对应,否则反序列化会出现意想不到的问题。

Step2、编译proto文件,生成特定语言数据的数据定义代码

安装proto编译器方法,Windows版本:

https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1选择protoc-3.7.1-win32.zip 下载解压,将/bin/protoc.exe路径添加到环境变量中。运行编译器,指定源目录(你的应用程序源码目录——如果你不提供这个目录,默认就是当前目录),目标目录(你的应用程序编译后生成的代码的目录;通常用$SRC_DIR),还有你.proto文件的目录路径。在这种情况下,你可以

代码语言:javascript
复制
protoc -I=$SRC_DIR --cpp_out=$DST_DIR$SRC_DIR/addressbook.proto

如果你想生成Python的类,所以你要用--python_out选项——也有类似的选项支持其它语言,例如:

代码语言:javascript
复制
protoc -I=./ --python_out=./ ./addressbook.proto

Step3、将生成的.h、.c文件都引用到项目文件中

生成的C++的protocol buffer代码每个字段会生成一个has函数(has_value)、clear清除函数(clear_value)、set函数(set_value)、get函数(number和mutable_value)。这儿解释下get函数中的两个函数的区别,对于原型为const std::string&number() const的get函数而言,返回的是常量字段,不能对其值进行修改。但是在有一些情况下,对字段进行修改是必要的,所以提供了一个mutable版的get函数,通过获取字段变量的指针,从而达到改变其值的目的。

对于单一的成员变量设置值,可以使用对应的set_value函数;

对于repeated类型变量,可是使用对应的add_value()函数增加变量值;

对于union等不确定的类型变量,可以使用mutable_value()通过返回的指针设置变量值。

序列化反序列化:通过每个protocolbuffer类都有读message或写message的方法给你选择通过用protocol buffer binary format。包括:

SerializeToString(buff,length):序列化这个message和以字符串的方式返回。这是二进行字节,可以使用str类型作为一个方便的容器,类似的还有SerializeToArray()。

ParseFromString(buff,length):从给出的字符串中解析一条message。类似的还有ParseFromArray()

这里有只是一些使用解析和序列化的选项。此外,也会以看 Message API reference,查看完整的列表。

注意使用之前要引入Google的protobuf库,就可以正式使用pb协议编码解码数据

参考文档:

https://juejin.im/post/5bb597c2e51d450e6e03e42d

https://blog.csdn.net/losophy/article/details/17006573

https://developers.google.com/protocol-buffers/docs/downloads

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档