安装编译protobuf
// protoTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "user.pb.h"
#include <string>
#include <google/protobuf/message_lite.h>//所有proto数据都可以用这个格式传输
using namespace std;
int i = 1;
void send(google::protobuf::MessageLite* data)//模拟发送
{
cout <<"第" << i++<<"包" << endl;
cout << "发送成功" << endl;
}
void recv(google::protobuf::MessageLite* data, google::protobuf::MessageLite* recvdata)//第一个参数加入是接收到数据 第二个是接收包
{
//接受这里 因为解析发送了长度 我这边没写 所以接受跳过 你看下面代码就知道接收了
}
//void net::TcpServer::ParseProtoBuffData(S_CLIENT_BASE* c, ::google::protobuf::MessageLite* messageLite, size_t len)
//{
// char myRode[512];
// char* p = myRode;
// if (len > 512)
// {
// p = new char[len];
// }
// _read(c->ID, p, len); 这里解析数据放到p里面
// messageLite->ParsePartialFromArray(p, len);//这里根据长度解析 从P解析到数据里面
// if (len > 512)
// {
// delete[] p;
// p = nullptr;
// }
//}
int main()
{
std::cout << "Hello World!\n";
cout << pb_user::account_not_exist << endl;
pb_user::sc_regist_account data;//这里代表这个数据格式
string a("啊啊啊");
string password("啊啊");//protobuf不能发送中文 但是可以用base64加密后 能发送 我之前有写个文章
data.set_account(a);//a填充a到传输协议里面
data.set_password(password);//这里只是填充了 还没压缩
char buff[512];//这个是缓冲池 填充进去的 对应代码 看我服务器哪里
data.SerializePartialToArray(buff,data.ByteSizeLong());//这里压缩进了buff里面 buff别看是char数组 其实进行压缩后 这里已经不可见了 进行了位运算 算法 然后压缩的很小了
cout << buff << endl;
cout << data.ByteSizeLong() << endl;
send(&data);
//数据填充满了 你就可以发送了 但是 required 类型的 必须填写 不然解析的时候会发现没有这个数据 就会报错 还有个可选填写的 op开头的 我没用 repeated 这个替代了可选 代表0-n个 但是这个格式不一样 因为是数组 我写一个 给你看看把
pb_user::sc_user_login_hall data1;
for (int i = 0; i < 10; ++i)
{
data1.add_roomid(i);//这个是填充repeated类型的
}
//还有就是message 包含message的情况
pb_user::testdata data2;
data2.set_id(1);//这不是message
auto info = data2.add_data();
string c("aaaaaaa");
string d("bbbbbbb");
info->set_account(c);//填充a到传输协议里面 他会进行数据压缩
info->set_password(d);//
send(&data);
//这样data2也填充好了 我先把data1屏蔽了 这个没有填充玩所有数据 不过不解析也没问题 下面开始解析 就是接收方的事了 这些数据直接send 发送就行了 我server里面有 这个格式同意格式使用的一个库
//接受
pb_user::cs_regist_account data3;// 这个跟上面不一样 是2个message 正来说 cs就是客户端发送服务器 sc就是代表服务器发给客户端 s代表server c代表client
data3.ParsePartialFromArray(&buff,data.ByteSizeLong());//这里我还是能获取长度的 其实我封装哪里 一样是根据这个填充的长度我要解析data1的数据 现在data3里面填充了data1的数据了 所以我是可以取出来的
cout << data3.account().c_str() << endl;//data1是没填充完的哪个 改成data了
cout << data3.password().c_str() << endl;
}
syntax = "proto2";
package pb_user;
option optimize_for = LITE_RUNTIME;
enum cmd_code
{
//注册、登录等主ID
MainID_Login =10;
MainID_Register = 20;
//通知主ID
MainID_Notify = 101;
Notify_AssID_KickoutHall = 1; //通知玩家被踢出大厅,该账号在其他设备上登录
Notify_AssID_UpdateInfo = 2; //通知最新玩家数据
Notify_AssID_RechargeInfo = 3;//通知充值信息
}
enum error_code{
//注册账号已经存在
account_exist = 1;
//游客账号设备不能空
device_code_none = 2;
//账号不存在
account_not_exist = 3;
//密码不正确
password_error = 4;
//账号禁用
account_disable = 5;
//游客登陆流程不对 必须调用注册才能登陆
visitor_login_error = 6;
//session错误 大厅连接不能恢复 需要重新登陆
session_error = 7;
//系统维护
system_maintenance=8;
password_error_length=9;
account_error_length=10;
}
//注册账号
message cs_regist_account
{
required string account = 1;
required string password = 2;//正常密码
}
//注册账号返回信息
message sc_regist_account
{
required string account = 1;
required string password = 2;//MD5加密后的数据 后续带着这个请求登录借口
}
//登陆
message cs_user_login_hall
{
required string account = 1;
required string password = 2; //使用安全码_密码 然后MD5加密
}
message testdata
{
required int32 id = 5; //在线用户索引ID
repeated cs_user_login_hall data =1;//message内包含另外个message
}