某项目实战分析代码二
某项目实战分析代码二
- 此次分析的是protobuf的使用
- 操作流程
- 具体实现
- 3. 业务数据分析
- 3.1 客户端
- 3.2 服务器端
- 简单案例
此次分析的是protobuf的使用
Protocol Buffer( 简称 Protobuf) 是Google公司内部的混合语言数据标准,它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或RPC 数据交换格式。
Protobuf是一个纯粹的展示层协议,可以和各种传输层协议一起使用,Protobuf的文档也非常完善。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。
Protobuf支持的数据类型相对较少,不支持常量类型。由于其设计的理念是纯粹的展现层协议,目前并没有一个专门支持Protobuf的RPC框架。
更多资料可查看:https://developers.google.com/protocol-buffers/
操作流程
- 准备数据
- 复合类型: 结构体/ 类
- 基础类型
- 创建一个新文件
xxx.proto
- 将我们要序列化的数据 -> 写入到proto文件
- 有语法格式
- 通过一个命令
protoc
将xxx.proto
文件生成一个c++的类
- 对应一个头文件/ 源文件
- 操作命令-> 在window终端中:
protoc xxx.proto --cpp_out=./
- 直接使用这个类
- 里边有对数据操作的api
- 读数据 api
- 方法名字
变量名()
- 写数据 api
- 方法名字:
set_变量名(arg)
具体实现
// 要序列化的数据
struct Persion
{int id;string name;string sex; // man womanint age;
};
在.proto文件中定义消息格式
// protobuf的版本
syntax = "proto3"; // proto2
// 组织Persion结构体
// 语法格式
message 关键字(相当于被创建出的类的名字)
{// 成员变量数据类型 变量名 = 变量的编号; // 编号从1开始, 不能重复
}// .proto文件 生成 c++ 类的命令
protoc proto文件名 --cpp_out=生成目录
.proto类型 | **C++**类型 | 备注 |
---|---|---|
double | double | 64位浮点数 |
float | float | 32位浮点数 |
int32 | int32 | 32位整数 |
int64 | int64 | 64位整数 |
uint32 | uint32 | 32位无符号整数 |
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 | 自定义的消息类型 |
-
repeated限定修饰符
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; }
-
枚举
syntax = "proto3"; // 定义枚举 enum Color {Red = 0; // protbuf中第一个枚举值必须为0Green = 6;Blue = 9; } message Persion {int32 id = 1; // 编号从1开始bytes name = 2;string sex = 3;int32 age = 4;Color color = 5; // 枚举变量 }
-
proto文件的导入
// Persion.proto syntax = "proto3"; // 导入另外一个proto文件 import "Info.proto";enum Color {Red = 0; // protbuf中第一个枚举值必须为0Green = 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文件中的类 }
// Info.proto syntax = "proto3";message Info {bytes address = 1; // 地址int32 number = 2; // 门牌号 }
-
包 -> 命名空间
// Persion.proto syntax = "proto3"; // 导入另外一个proto文件 import "Info.proto"; // 添加命名空间 package itcast; // Persion类属于itcast这个命名空间enum Color {Red = 0; // protbuf中第一个枚举值必须为0Green = 6;Blue = 9; }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文件中的类 }
// Info.proto syntax = "proto3"; // Persion类属于itheima这个命名空间 package itheima;message Persion {bytes address = 1; // 地址int32 number = 2; // 门牌号 }
-
使用protobuf编译器生成C++类
# protobuf编译器, 编译源码得到的 protoc.exe # 语法 # --cpp_out 生成的c++类的位置 protoc.exe xxx.proto --cpp_out=目录
-
使用C++ API来读写消息
3. 业务数据分析
3.1 客户端
// 准备要发送的数据
struct RequestMsg
{//1 密钥协商 //2 密钥校验; // 3 密钥注销int cmdType; // 报文类型string clientId; // 客户端编号string serverId; // 服务器端编号string sign;string data;
};
message RequestMsg
{int32 cmdType;bytes clientId;
}
3.2 服务器端
struct RespondMsg
{bool rv; // 返回值int seckeyid; // 对称密钥编号 keysnstring clientId; // 客户端编号string serverId; // 服务器编号string data; // 服务器端随机数
};
简单案例
1.新建protobuf文件
syntax = "proto3";message Persion{int32 id = 1; // 编号从1开始bytes name = 2;string sex = 3;int32 age = 4;}
2.按住shift+左键,进入powerShell,执行命令生成文件