文章目录
- 应用层协议设计
- protobuf 序列化
- protobuf的原理
- 定义message
- 编译message文件
- 应用protobuf
- Message 基本用法
- Message 嵌套使用
- 具体操作
点击我, 到底部
应用层协议设计
- 通信双方交换数据的格式与顺序
- 通信双方应该采取的动作
用户登陆模块
- 短信获取
获取短信请求mobile_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
mobile | string | required | 手机号码, 必须为大陆手机取 11 位数字 |
获取短信响应 mobile_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
icode | int32 | required | 成功保存验证码, 失败保存0 |
desc | string | optional | 可选, 失败时描述失败原因 |
登陆验证
- 短信验证请求
login_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
mobile | string | required | 手机号码, 必须为大陆手机取 11 位数字 |
icode | int32 | required | 验证码 |
- 短信验证响应
login_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
desc | string | optional | 可选, 失败时描述失败原因 |
充值
- 充值请求
recharge_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
mobile | string | required | 手机号码, 必须为大陆手机取 11 位数字 |
amount | int32 | required | 充值数量 |
- 充值响应
recharge_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
desc | string | optional | 可选, 失败时描述失败原因 |
balance | int32 | required | 最新余额 |
- 余额查询
account_balance_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
mobile | string | required | 手机号码, 必须为大陆手机取 11 位数字 |
- 余额查询响应
account_balance_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
desc | string | optional | 可选, 失败时描述失败原因 |
balance | int32 | required | 失败置为 -1 |
查询充值记录
- 充值记录请求
list_account_records_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
mobile | string | required | 手机号码, 必须为大陆手机取 11 位数字 |
- 充值记录响应
list_account_records_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
desc | string | optional | 可选, 失败时描述失败原因 |
records | account_record | required | ==>> |
==>>
复制代码
1
2
3
4
5
6message account_record { required int32 type = 1; // 0 : 骑行消费, 1 : 充值, 2 : 退款 required int32 limit = 2; // 消费或者充值金额 required uint64 timestamp = 3; // 记录发生时的时间戳 }
查询骑行记录
- 骑行记录查询请求
list_travel_records_request
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 手机号码, 必须为大陆手机取 11 位数字 |
- 骑行记录查询响应
list_travel_records_response
字段名 | 类型 | 属性 | 字段描述 |
---|---|---|---|
code | int32 | required | 响应代号: 200-成功 400-失败 |
desc | string | optional | 可选, 失败时描述失败原因 |
records | travel_record | required | xxx |
mileage | double | required | 骑行里程 |
discharge | double | required | 排放 |
calorie | double | required | 卡路里 |
xxx
复制代码
1
2
3
4
5
6
7
8
9message travel_record { required uint64 stm = 1; // start timestamp required uint32 duration = 2; // 骑行时长 required uint32 amount = 3; // 所耗金额 }
protobuf 序列化
复制代码
1
2
3protobuf是一种比json和xml等序列化工具更加轻量和高效的结构化数据存储格式, 性能比json和xml真的强很多,毕竟google出品。
protobuf官网
请科学上网
protobuf的原理
protobuf 的安装
复制代码
1
2
3
4
5
6
7
8
9
10
11apt-get install autoconf automake libtool curl make g++ unzip $ git clone https://github.com/protocolbuffers/protobuf.git $ cd protobuf $ git submodule update --init --recursive $ ./autogen.sh $ ./configure $ make $ make check $ sudo make install $ sudo ldconfig
定义message
所有的message必须定义到一个文件中,且文件的后缀名为.proto。例如我们定义的bike.proto文件
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97syntax = "proto2"; package tutorial; message mobile_request { required string mobile = 1; } message mobile_response { required int32 code = 1; //响应代号 required int32 icode = 2; //验证码 optional string data = 3; //失败原因 } message login_request { required string mobile = 1; // 手机号码 required int32 icode = 2; // 验证码 } message login_response { required int32 code = 1; // 响应代号 optional string desc = 2; // 验证码 } message recharge_request { required string mobile = 1; // 手机号码 required int32 amount = 2; // 充值金额 } message recharge_response { required int32 code = 1; // 响应代号 optional string desc = 2; // 验证码 required int32 balance = 3; // 最新的余额 } message account_balance_request { required string mobile = 1; } message account_balance_response { required int32 code = 1; // 响应代号 optional string desc = 2; // 验证码 required int32 balance = 3; } message list_account_records_request { required string mobile = 1; } message list_account_records_response { required int32 code = 1; // 响应代号 optional string desc = 2; // 验证码 message account_record { required int32 type = 1; // 0 : 骑行消费, 1 : 充值, 2 : 退款 required int32 limit = 2; // 消费或者充值金额 required uint64 timestamp = 3; // 记录发生时的时间戳 } repeated account_record records = 3; } message list_travel_records_request { required string mobile = 1; } message list_travel_records_response { required int32 code = 1; // 响应代号 optional string desc = 2; // 验证码 message travel_record { required uint64 stm = 1; // start timestamp required uint32 duration = 2; // 骑行时长 required uint32 amount = 3; // 所耗金额 } required double mileage = 3; // 里程 required double discharge = 4; // 排放 required double calorie = 5; // 卡路里 repeated travel_record records = 6; }
编译message文件
编译语法:
复制代码
1
2protoc -I=$SRC_DIR --cpp_out=$DST_DIR bike.proto
SRC_DIR 表示proto文件所在的目录,cpp_out指定了生成的代码的路径, bike.proto指proto文件名。
复制代码
1
2protoc -I=./ --cpp_out=./ bike.proto
这样在当前目录生成了bike.pb.cc和bike.pb.h两个文件。
编译生成的c++文件
复制代码
1
2g++ --std=c++11 example.cc bike.pb.cc -lprotobuf
应用protobuf
复制代码
1
2把生成了protocol.pb.cc和protocol.pb.h加入到工程,那么接着就是调用一些API,完成序列化和反序列化。
API说明
Message 基本用法
范例1: example1.cc
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "bike.pb.h" #include <string> #include <iostream> using namespace std; using namespace tutorial; int main(void) { std::string data; //存储序列化的消息 //客户端发送请求 { mobile_request mr; mr.set_mobile("18684518289"); mr.SerializeToString(&data); cout<<"序列化后的数据["<<data.length()<<"]: "<< data << endl; cout<<hex<<(int)*((char*)data.c_str())<<endl; cout<<hex<<(int)*((char*)data.c_str() + 1)<<endl; //客户端发送data send(sockfd, data.c_str(), data.length()); } //服务器端接受请求 { //receive(sockfd, data, ...); mobile_request mr; mr.ParseFromString(data); cout<<"客户端手机号码: " << mr.mobile() << endl; } return 0; }
Message 嵌套使用
范例2: example1.cc
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49#include "bike.pb.h" #include <string> #include <iostream> using namespace std; using namespace tutorial; int main(void) { std::string data; //存储序列化的消息 //客户端发送请求 { list_account_records_response larr; larr.set_code(200); larr.set_desc("ok"); for(int i=0; i<5; i++) { list_account_records_response_account_record * ar = larr.add_records(); ar->set_type(0); ar->set_limit(i * 100); ar->set_timestamp(time(NULL)); } printf("recoreds size : %dn", larr.records_size()); larr.SerializeToString(&data); //客户端发送data send(sockfd, data.c_str(), data.length()); } //服务器端接受请求 { list_account_records_response larr; larr.ParseFromString(data); printf("recoreds size : %dn", larr.records_size()); printf("code: %dn", larr.code()); for(int i=0; i<larr.records_size(); i++) { const list_account_records_response_account_record &ar = larr.records(i); printf("limit: %dn", ar.limit()); } //cout<<"客户端手机号码: " << mr.mobile() << endl; } return 0; }
具体操作
第一步新建一个, bike.proto 文件
第二步: 编译
生成文件
和.cc 整合
运行结果
第二个例子, 就不具体操作了
点击我, 到顶部最后
以上就是幸福服饰最近收集整理的关于Protobuf 的简单使用例子的全部内容,更多相关Protobuf内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复