C++学习之序列化protobuf使用

目录

1.知识点概述new

2.如何使用uml描述一个类

3.uml描述继承关系

4.uml中描述关联关系

5.uml中对组合和聚合的描述

6.uml中的依赖关系的描述

7.uml总结

8.序列化介绍

9.网络通信中常见的问题分析

10.常用数据序列化方式

11.probobuf使用步骤

12.编写proto文件并生成对应的类

13.protobuf生成的类分析

14.复习

15.protobuf序列化数据和解析

16.protobuf中数据的使用-repeated

17.protobuf中使用枚举

18.在一个proto中导入其他proto文件

19.测试在一个类中包含其他对象

20.protobuf中添加命名空间

21.要实现的编解码类


1.知识点概述new

> 序列化 (Serialization)将对象的**状态信息转换为**可以**存储或传输的形式的过程**,与之相对应的过程称之为反序列化(Unserialization)。==**序列化和反序列化主要用于解决在跨平台和跨语言的情况下, 模块之间的交互和调用,但其本质是为了解决数据传输问题**==。

>

> 实现数据序列化:

>

> - 要有原始数据

> - 复合类型 -> 最常见的情况

> - 基础数据类型

> - 通过某些方式 -> 另外一种形式的数据

> - 得到的数据干啥? -> 目的: 进行分发, 分发到不同的终端/平台, 保证不同的平台能正确解析

> - 网络传输

> - 磁盘拷贝

2.如何使用uml描述一个类

> <font color="red">序列化目的不是为了加密, 为的是数据的跨平台传输</font>

>

> 序列化的整体过程:

>

> - 发送端

> - 原始数据 -> 序列化 (编码) -> 特殊格式的字符串

> - 发送这个字符串

> - 接收端:

> - 接收数据

> - 特殊格式的字符串 -> 反序列化 (解码) -> 原始数据

> - 对原始数据进行处理

3.uml描述继承关系

1.1 网络通信中的问题分析

发送过程中遇到的一些问题?

  • 平台不同

  • 32bit / 64bit

  • long

  • 平台不同, 某些数据类型占用的内存大小不同

  • 如果不是字符串, 需要进行字节序转换

  • 字符串没有字节序问题, 字符在内存中只占一个字节

  • 如果发送的是结构体

4.uml中描述关联关系

```c

struct Test

{

int number;

char buf[12];

long sex;

};

Test t;

send()/write()

send(fd, (void*)t, sizeof(t), 0);

```

  • 大小端问题

  • 语言不同

  • 语言不同数据类型占用的内存有可能不同

  • c -> char -> 1字节

  • java -> char -> 2字节

  • 字节对齐问题

5.uml中对组合和聚合的描述

  1. XML( Extensible Markup Language )类似于html

> XML是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点。XML历史悠久,其1.0版本早在1998年就形成标准,并被广泛使用至今。

>

> XML的最初产生目标是对互联网文档进行标记,所以它的设计理念中就包含了对于人和机器都具备可读性。 但是,当这种标记文档的设计被用来序列化对象的时候,就显得冗长而复杂。

>

> XML基本格式:

```xml

6.uml中的依赖关系的描述

<?xml version="1.0" encoding="utf-8"?>

<Library>

<Type name="小说">

<Book author="J.K.ROWLING" price="12$">哈利波特1</Book>

<Book author="J.K.ROWLING" price="12$">哈利波特2</Book>

<Book author="J.K.ROWLING" price="12$">哈利波特3</Book>

<Book author="J.K.ROWLING" price="12$">哈利波特4</Book>

</Type>

<Type name="历史">

<Book author="司马迁" price="20$">史记</Book>

</Type>

</Library>

7.uml总结

  1. Json( JavaScript Object Notation )

> JSON起源于弱类型语言Javascript,它的产生来自于一种称之为"关联数组(Associative array)"的概念,其本质是就是采用"键值对"的方式来描述对象。

>

> JSON格式保持了XML的人眼可读的优点,非常符合工程师对对象的理解。

>

> 相对于XML而言,序列化后的数据更加简洁(XML所产生序列化之后文件的大小接近JSON的两倍),而且其协议比较简单,解析速度比较快。

>

> JSON格式具备Javascript的先天性支持,所以被广泛应用于Web browser的应用常景中,是Ajax的事实标准协议。

>

> 更多资料可查看:<http://json.org/\>

8.序列化介绍

```json

// json是一种数据格式, 不是语言, 和平台语言无关

// json数组

整形, 浮点型, 布尔类型, 字符串, json数组, json对象

12, 12.44, true, "hello", \[1,2,3\]

// json对象

{

"key":"value"

}

json对象中是n个键值对

key: 必须是字符串

value:

整形

浮点型

布尔

字符串

json数组

json对象

9.网络通信中常见的问题分析

注意事项:

在一个文件中只能存储一个大的数组或者对象, 但是可以嵌套使用

原素和原始之间使用逗号间隔(一个键值对视为一个元素)

最后一个元素后边没有逗号

{

"lilei":"112334",

"tom":"helolll",

"lucy":"xxxxyyyy"

}

"张三", "历史"

{

"张三":{

"father":"张三丰",

"mother":"xxxx",

"sister""xxx",

"favorite":["足球", "乒乓", "游泳"]

}

"李四":{

}

}

10.常用数据序列化方式

Protocol Buffer

  1. ASN.1 抽象语法标记(Abstract Syntax Notation One)

  2. boost 序列化的类

2. protobuf

> Protocol Buffer( 简称 Protobuf) 是Google公司内部的混合语言数据标准,它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或RPC 数据交换格式。

>

> Protobuf是一个纯粹的展示层协议,可以和各种传输层协议一起使用,Protobuf的文档也非常完善。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。

>

> Protobuf支持的数据类型相对较少,不支持常量类型。由于其设计的理念是纯粹的展现层协议,目前并没有一个专门支持Protobuf的RPC框架。

>

> 更多资料可查看:<https://developers.google.com/protocol-buffers/\>

11.probobuf使用步骤

12.编写proto文件并生成对应的类

> - 准备数据

> - 复合类型: 结构体/ 类

> - 基础类型

> - 创建一个新文件 `xxx.proto`

> - 将我们要序列化的数据 -> 写入到proto文件

> - 有语法格式

> - 通过一个命令 `protoc`将`xxx.proto`文件生成一个c++的类

> - 对应一个头文件/ 源文件

> - 操作命令-> 在window终端中: `protoc xxx.proto --cpp_out=./`

> - 直接使用这个类

> - 里边有对数据操作的api

> - 读数据 api

> - 方法名字 `变量名()`

> - 写数据 api

> - 方法名字: `set_变量名(arg)`

13.protobuf生成的类分析

// 要序列化的数据

struct Persion

{

int id;

string name;

string sex; // man woman

int age;

};

int id;

```

  • 在.proto文件中定义消息格式

```protobuf

// protobuf的版本

syntax = "proto3"; // proto2

// 组织Persion结构体

// 语法格式

message 关键字(相当于被创建出的类的名字)

{

// 成员变量

数据类型 变量名 = 变量的编号; // 编号从1开始, 不能重复

}

14.复习

| .proto类型 | **C++**类型 | **备注** |

| :--------: | :-------------: | ------------------------------------------------------------ |

| double | double | 64位浮点数 |

| float | float | 32位浮点数 |

| int32 | int32 | 32位整数 |

| int64 | int64 | 64位整数 |

| uint32 | uint32 | 32位无符号整数 |

| uint64 | uint64 | 64位无符号整数 |

15.protobuf序列化数据和解析

| uint64 | uint64 | 64位无符号整数 |

| sint32 | sint32 | 32位整数,处理负数效率比int32更高 |

| sint64 | sint64 | 64位整数,处理负数效率比int64更高 |

| fixed32 | uint32 | 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。 |

| fixed64 | uint64 | 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。 |

| sfixed32 | int32 | 总是4个字节 |

| sfixed64 | int64 | 总是8个字节 |

| bool | bool | 布尔类型 |

| string | string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本 |

| bytes | string | 处理多字节的语言字符、如中文 |

| enum | enum | 枚举 |

| message | object of class | 自定义的消息类型 |

16.protobuf中数据的使用-repeated

  • repeated限定修饰符

```protobuf

syntax = "proto3";

message Persion

{

int32 id = 1; // 编号从1开始

bytes name = 2;

string sex = 3;

int32 age = 4;

}

// 要求name有多个 -> 数组

syntax = "proto3";

message Persion

{

int32 id = 1; // 编号从1开始

// vector<string> name;

repeated bytes name = 2; // name可以在程序中创建多个, 在程序中作为动态数组来使用

string sex = 3;

int32 age = 4;

}

17.protobuf中使用枚举

枚举

```protobuf

syntax = "proto3";

// 定义枚举

enum Color

{

Red = 0; // protbuf中第一个枚举值必须为0

Green = 6;

Blue = 9;

}

message Persion

{

int32 id = 1; // 编号从1开始

bytes name = 2;

string sex = 3;

int32 age = 4;

Color color = 5; // 枚举变量

}

18.在一个proto中导入其他proto文件

  • proto文件的导入

```protobuf

// Persion.proto

syntax = "proto3";

// 导入另外一个proto文件

import "Info.proto";

enum Color

{

Red = 0; // protbuf中第一个枚举值必须为0

Green = 6;

Blue = 9;

}

message Persion

{

int32 id = 1; // 编号从1开始

repeated bytes name = 2;

string sex = 3;

int32 age = 4;

Color color = 5;

Info info = 6; // Info对象, 导入的proto文件中的类

}

19.测试在一个类中包含其他对象

```protobuf

// Info.proto

syntax = "proto3";

message Info

{

bytes address = 1; // 地址

int32 number = 2; // 门牌号

}

```

20.protobuf中添加命名空间

包 -> 命名空间

```protobuf

// Persion.proto

syntax = "proto3";

// 导入另外一个proto文件

import "Info.proto";

// 添加命名空间

package itcast; // Persion类属于itcast这个命名空间

enum Color

{

Red = 0; // protbuf中第一个枚举值必须为0

Green = 6;

Blue = 9;

}

21.要实现的编解码类

message Persion

{

int32 id = 1; // 编号从1开始

repeated bytes name = 2;

string sex = 3;

int32 age = 4;

Color color = 5;

// 命名空间.类名

itheima.Info info = 6; // Info对象, 导入的proto文件中的类

}

```

相关推荐
爱看书的小沐25 分钟前
【小沐学GIS】基于C++绘制三维数字地球Earth(QT5、OpenGL、GIS、卫星)第五期
c++·qt·opengl·imgui·地球·卫星·gis地球
sealaugh3232 分钟前
AI(学习笔记第一课) 在vscode中配置continue
人工智能·笔记·学习
天堂的恶魔94634 分钟前
C++项目 —— 基于多设计模式下的同步&异步日志系统(1)
c++
每次的天空1 小时前
Android学习总结之OKHttp拦截器和缓存
android·学习·okhttp
不知道叫什么呀1 小时前
【5G-A学习】ISAC通信感知一体化学习小记
学习·5g·aigc·我的ai老师
杨某一辰1 小时前
库magnet使用指南
c++·多线程·
爱编程的鱼1 小时前
深入学习任何技术的实用指南
学习
肖恩想要年薪百万2 小时前
自用:在使用SpringBoot做学生信息管理系统时遇到的问题
java·spring boot·后端·学习·spring·intellij-idea
ricky_fan3 小时前
Leetcode39:组合总和——回溯算法
开发语言·c++·leetcode
爱看烟花的码农3 小时前
LeetCode 热题 8/100打卡
c++·python·算法·leetcode