Protobuf快速入门

1 Protobuf简介

1.1 What is Protobuf?

       protobuf也叫protocol buffer是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。

       由于它是一种二进制的格式,比使用 xml 、json进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

1.2 Protobuf的优缺点

1.2.1 优点

  • 性能好/效率高
  • 代码生成机制
  • 支持“向后兼容”和“向前兼容”
  • 支持多种编程语言

1.2.2 缺点

  • 应用不够广(相比xml和json)
  • 二进制格式导致可读性差
  • 缺乏自描述

为什么protobuf的性能比json高呢?这就得从protobuf的压缩原理来分析了。

图上这个json长度为27字节,但是为了表示这个数据结构,它用了9个字节(就是那些大括号、引号、冒号之类的,他们是白白多出来的)来表示那些额外添加的无意义数据。

msgpack的优化在图上展示的也比较清楚了,省去了特殊符号,用特定编码对各种类型进行定义,比如上图的A7,其中前四个bit A就是表示str的编码,而且它表示这个str的长度只用半个字节就可以表示了,也就是后面的7,因此A7的意思就是表示后面是一个7字节长度的string。
       有的同学就会问了,对于长度大于15(二进制1111)的string怎么表示呢?这就要看messagepack的压缩原理了。(MessagePack简介及使用 - 简书

2 Protobuf安装

2.1 Ubuntu环境搭建

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

2.2 protobuf-c插件安装

如果想将.proto编译成.c文件的话,需要装protobuf-c的插件,步骤如下:

The steps of installing protobuf-c plugin are as follows:

  1. sudo apt install git(如果已安装git,则跳过);
  2. git clone GitHub - protobuf-c/protobuf-c: Protocol Buffers implementation in C;
  3. sudo ./configure && make && make install;
编译命令 protoc --c_out=. example.proto

3 Protobuf基本语法

基本语法见Protobuf语言指南 - dkcndk - 博客园

3.1三个关键字required、optional、repeated

  • required关键字

       顾名思义,就是必须的意思,数据发送方和接收方都必须处理这个字段,不然还怎么通讯呢?

  • optional关键字

       字面意思是可选的意思,具体protobuf里面怎么处理这个字段呢,就是protobuf处理的时候另外加了一个bool的变量,用来标记这个optional字段是否有值,发送方在发送的时候,如果这个字段有值,那么就给bool变量标记为true,否则就标记为false,接收方在收到这个字段的同时,也会收到发送方同时发送的bool变量,拿着bool变量就知道这个字段是否有值了,这就是option的意思。

       这也就是他们说的所谓平滑升级,无非就是个兼容的意思。其实和传输参数的时候,给出数组地址和数组数量是一个道理。

  • repeated关键字

       字面意思大概是重复的意思,其实protobuf处理这个字段的时候,也是optional字段一样,另外加了一个count计数变量,用于标明这个字段有多少个,这样发送方发送的时候,同时发送了count计数变量和这个字段的起始地址,接收方在接受到数据之后,按照count来解析对应的数据即可。

4 代码案例

4.1 c

4.1.1 编码(encoding)

① 创建一个简单文件: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 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有对象的野指针°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值