一:安装
地址是:https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz,wget一下就可以了。
然后就是安装三部曲:1. ./configure 2.make 3.make check 4.sudo make install (额,多了第三步)
不过安装后可能会报错,protobuf的默认安装路径是/usr/local/lib,而/usr/local/lib不在ubuntu体系默认的LD_LIBRARY_PATH里,所以就找不到lib,在/etc/ld.so.conf.d/目录下创建bprotobuf.conf文件,写入/usr/local/lib,退出。输出命令sudo ldconfig即可。
二:用法
1.消息类型
如下,类似于C++中的class:
message water_meter{
required uint64 id = 1;
optional string name = 2;
optional uint64 degree = 3
1.指定字段类型
在上面的例子中,所有字段都是标量类型:两个整型(page_number和result_per_page),一个string类型(query)。当然,你也可以为字段指定其他的合成类型,包括枚举(enumerations)或其他消息类型。
2.分配标识号
正如上述文件格式,在消息定义中,每个字段都有唯一的一个标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改 变。注:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。切记:要为将来有可能添加的、频繁出现的标识号预留一些标识号。
最小的标识号可以从1开始,最大到229 - 1, or 536,870,911。不可以使用其中的[19000-19999]的标识号, Protobuf协议实现中对这些进行了预留。如果非要在.proto文件中使用这些预留标识号,编译时就会报警。
3.指定字段规则
所指定的消息字段修饰符必须是如下之一:
required:一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的;
optional:消息格式中该字段可以有0个或1个值(不超过1个)
repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复
三:编译方法见Makefile:
all:proto_msg write read
proto_msg:
protoc --cpp_out=. msg.proto
write:msg.pb.cc writer.cpp
g++ msg.pb.cc writer.cpp -o write `pkg-config --cflags --libs protobuf`
read:msg.pb.cc reader.cpp
g++ msg.pb.cc reader.cpp -o read `pkg-config --cflags --libs protobuf`
.PHONY:clean
clean:
rm -rf write *.pb.cc *.pb.h read write message
四:实例
msg.proto:
package three_meter;
message water_meter{
required uint64 id = 1;
optional string name = 2;
optional uint64 degree = 3;
}
message electricity_meter{
required uint64 id = 1;
optional string name = 2;
optional uint64 degree = 3;
}
message fulegas_meter{
required uint64 id = 1;
optional string name = 2;
optional uint64 degree = 3;
}
用protoc编译该proto文件会生成.pb.cc文件和.pb.h文件,相当于一个库一样,你自己在自己的程序中调用就可以了。
writer.cpp
#include "msg.pb.h"
#include <iostream>
#include <fstream>
using namespace std;
using namespace three_meter;
int main()
{
three_meter::water_meter msg1;
msg1.set_id(1007);
msg1.set_name("weeyanghuang@gmail.com");
msg1.set_degree(52);
fstream out("message", ios::out|ios::trunc|ios::binary);
if(!msg1.SerializeToOstream(&out)){
cerr<<"failed to write msg"<<endl;
return -1;
}
return 0;
}
read.cpp
#include "msg.pb.h"
#include <iostream>
#include <fstream>
using namespace std;
using namespace three_meter;
void listmsg(const three_meter::water_meter& msg)
{
cout<<"user id: "<<msg.id()<<endl;
cout<<"user name: "<<msg.name()<<endl;
cout<<"water degree: "<<msg.degree()<<endl;
}
int main()
{
three_meter::water_meter msg1;
fstream in("message", ios::in|ios::binary);
if(!msg1.ParseFromIstream(&in)){
cerr<<"failed to parse address book"<<endl;
return -1;
}
listmsg(msg1);
return 0;
}
执行./write和./read后输出如下:
五:优势
那么为什么用protobuf,而不用xml呢?
在设计架构业务类的数据传输协议的时候,对于追求数据传输性能和带宽都有严格要求,如何实现数据的高效实时传输而又不对带宽造成太大的压力,
就可以选protobuf。
这个Google公司发布的一套开源编码规则,基于二进制流的序列化传输,可以转换成多种编程语言,几乎涵盖了市面上所有的主流编程语言。
来个对比:
如果要序列化结构化数据,
1.比起XML,更简单
2.比XML小3~10倍
3.比XML快20~100倍
4.语义定义明确自动生成数据存取类,更容易使用