Protobuf简单编写与使用

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;
}
  1. required:修饰的字段必须要设置
  2. optional:修饰的字段可以有0个值或者1个值
  3. repeated:修饰的字段可以重复任意多次
  4. 在使用期间,除非某个字段一定需要被设置,否则使用optional或者repeated代替
  5. 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;
}

猜你喜欢

转载自blog.csdn.net/qq_42708024/article/details/112245206