赞
踩
protobuf也叫protocol buffer是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。
由于它是一种二进制的格式,比使用 xml 、json进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
为什么protobuf的性能比json高呢?这就得从protobuf的压缩原理来分析了。
图上这个json长度为27字节,但是为了表示这个数据结构,它用了9个字节(就是那些大括号、引号、冒号之类的,他们是白白多出来的)来表示那些额外添加的无意义数据。
msgpack的优化在图上展示的也比较清楚了,省去了特殊符号,用特定编码对各种类型进行定义,比如上图的A7,其中前四个bit A就是表示str的编码,而且它表示这个str的长度只用半个字节就可以表示了,也就是后面的7,因此A7的意思就是表示后面是一个7字节长度的string。
有的同学就会问了,对于长度大于15(二进制1111)的string怎么表示呢?这就要看messagepack的压缩原理了。(MessagePack简介及使用 - 简书)
github源代码下载地址:GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format
源码包中的src/README.md, 有详细的安装说明,安装过程如下:
1、解压压缩包:
unzip protobuf-master.zip
2、进入解压后的文件夹:
cd protobuf-master
3、安装所需工具:
sudo apt-get install autoconf automake libtool curl make g++ unzip
4、自动生成configure配置文件:
./autogen.sh
5、配置环境:
./configure
6、编译源代码(时间比较长):
make
7、安装:
sudo make install
8、刷新动态库:
sudo ldconfig
如果想将.proto编译成.c文件的话,需要装protobuf-c的插件,步骤如下:
The steps of installing protobuf-c plugin are as follows:
编译命令 protoc --c_out=. example.proto
基本语法见Protobuf语言指南 - dkcndk - 博客园
顾名思义,就是必须的意思,数据发送方和接收方都必须处理这个字段,不然还怎么通讯呢?
字面意思是可选的意思,具体protobuf里面怎么处理这个字段呢,就是protobuf处理的时候另外加了一个bool的变量,用来标记这个optional字段是否有值,发送方在发送的时候,如果这个字段有值,那么就给bool变量标记为true,否则就标记为false,接收方在收到这个字段的同时,也会收到发送方同时发送的bool变量,拿着bool变量就知道这个字段是否有值了,这就是option的意思。
这也就是他们说的所谓平滑升级,无非就是个兼容的意思。其实和传输参数的时候,给出数组地址和数组数量是一个道理。
字面意思大概是重复的意思,其实protobuf处理这个字段的时候,也是optional字段一样,另外加了一个count计数变量,用于标明这个字段有多少个,这样发送方发送的时候,同时发送了count计数变量和这个字段的起始地址,接收方在接受到数据之后,按照count来解析对应的数据即可。
① 创建一个简单文件:amessage.proto,内容如下
- // [START declaration]
- syntax = "proto3";
- // [END declaration]
- message AMessage
- {
- int32 a = 1;
- int32 b = 2;
- }
② 通过命令行产生相应的.h和.c源文件。
protoc-c --c_out=. amessage.proto
③ main函数如下
- #include<stdio.h>
- #include<stdlib.h>
- #include"amessage.pb-c.h"
- #define myfilename "encoding.txt"
-
- int main (int argc,const char* argv[])
- {
- AMessage msg = AMESSAGE__INIT;// AMessage
- void* buf; // Buffer to storeserialized data
- unsigned int len; // Length of serialized data
-
- if(argc != 2 && argc != 3){ // Allow one or twointegers
- fprintf(stderr,"usage:amessage a [b]\n");
- return 1;
- }
-
- msg.a = atoi(argv[1]);
- if(argc == 3){
- msg.b = atoi(argv[2]);
- printf("msg.b=%d\n",msg.b);
- }
- len = amessage__get_packed_size(&msg);
- buf = malloc(len);
- amessage__pack(&msg, buf);
-
- FILE *pf = fopen(myfilename, "wb");
- fprintf(stderr,"Writing %d serialized bytes\n",len);// See the length of message
- fwrite(buf, len, 1, pf);
-
- free(buf);// Free theallocated serialized buffer
- fclose(pf);
- return 0;
- }

④ gcc编译源码,生成a.out
⑤ 执行a.out,生成encoding.txt
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。