Protobuf简单介绍
首先Protobuf是google公司提出的一种序列化方法,因为其在网络传输中优点较多,同时使用简单方便维护,因此现如今Protobuf以及逐渐取代Json来传输数据。
Protobuf与Json的对比
- 创建一个.proto文件,在该文件中定义了两个消息结构(student,teacher),
- 消息结构在C++中对应的类分别为:student、teacher
如果我们使用Protobuf进行传输时,只需要对类进行赋值即可。
//name、age、gender分别为student类与teacher类的属性
student类:
name:'张三'
age:20
gender:'男'
teacher类:
name:'张老师'
age:35
gender:'男'
如果我们使用Json进行数据传输时:
{"student":{"name":"张三","age":"20","gender":"男"},"teacher":{"name":"张老师","age":"35","gender":"男"})
Protobuf的语法
- 首先是定义语法格式,必须为第一行,表示后面的语法使用的是proto3语法,如果未写,则默认采用proto2语法。
syntax = "proto3"
- 导入其他proto文件
import other.proto
- 申明作用域,方式产生冲突,类似C++中的namespace
package “xxx”
- 定义消息格式
message Student{
required string name = 1;
required int32 age;
required string gender;
}
- required:修饰的字段必须要设置
- optional:修饰的字段可以有0个值或者1个值
- repeated:修饰的字段可以重复任意多次
- 在使用期间,除非某个字段一定需要被设置,否则使用optional或者repeated代替
- message类似于C++中的class
//创建PersonMsg.proto文件
syntax = "proto3";//使用proto3语法格式
package PersonMsg;
message Person
{
required string name = 1;
required int32 age = 2;
required string gender = 3;
optional string email = 4;
enum Profession //职业
{
Strudent = 1;
Teacher = 2;
Worker = 3;
}
enum PhoneType //电话卡类型
{
MOBILE = 0; //移动
Link = 1; //联通
}
message PhoneNumber{
requried string number = 1;
optional PhonType P_type = 2 [default = Link]; //电话卡默认类型为联通
}
repeated PhoneNumber number = 5; //可以重复多次
}
message PersonMessage
{
repeated Person personInfo = 1;
}
编译上述proto文件,会生成PersonMsg.pb.h与PersonMsg.pb.cc两个文件
- .h文件中存储的是消息类
- .cc文件中存储的是对消息的一些操作,set,clear,has等操作
- Protobuf序列与反序列
#include<iostream>
#include"PersonMsg.pb.h"
using namespace std;
char buf[1024];
int main()
{
PersonMsg::PersonMessage person;
PersonMsg::Person* p = person.add_personInfo();
p->set_name("张三");
p->set_age(20);
p->set_gender("男");
if(!p->has_email())//如果获取不到email,表示没有email则对其进行初始化
{
p->set_email("[email protected]");
}
PersonMsg::Person::PhoneNumber* phonenum = person.add_number();
phonenum->set_number("xxxxx");
phonenum->set_P_type("PersonMsg::Person::Link");//设置电话
int size = person.ByteSize();
person.SerializeToArray(buf,size); //序列化
PersonMsg::PersonMessage person2;
person2.ParseFromArray(buf,size); //发序列化
return 0;
}