Google.Protobuf
一、环境搭建
1、下载软件
https://github.com/protocolbuffers/protobuf/releases
2、为.exe文件设置环境变量
电脑 - 属性 - 高级系统设置 - 高级 - 环境变量 - 编辑用户变变量的Path变量-添加protoc.exe的所在目录
3、迁移include文件夹下的文件
将include/google文件夹移动到指定了环境变量的文件夹
二、编写.proto文件
syntax 来指明 使用版本
syntax = "proto2"; 或 syntax = "proto3";
package 对应于c#中的命名空间
创建命名空间(package)
示例:package Micro.IMSSDK;
结果:namespace Micro.IMSSDK { ... }
required 对应类的属性 (该变量必填)
optional 创建一个具有默认值的属性,通过[default=XXX]设置默认值,不添加默认为空置。如string默认为“”,int默认为0
enum 创建枚举
message 创建自定义类或内部类
repeated 对应list列表数据
import 导入引用
参考文档:
Protobuf 语法简明教程
https://blog.csdn.net/crazymakercircle/article/details/83904366
https://www.cnblogs.com/crazymakercircle/p/9937026.html
https://blog.csdn.net/sylar_d/article/details/51325987
三、生成代码
1、进入目录,输入cmd
2、复制google文件夹至目录
3、复制.proto文件至目录
4、生成csharp文件,如:protoc --csharp_out=./ chat.proto
proto2与proto3的基本语法
1)注释 // 2)选择哪个版本协议 syntax = "proto2" 或 syntax = "proto3" 3)定义一个协议类型,先从2讲起 syntax = "proto2" message my_person { // 消息开始 required string name = 1; required int32 age = 2; optional int32 sex = 3; repeated uint32 array_value = 4; } // 消息结束 4)每一行 // 字段规则(required) 字段类型(int32) 字段名字(age) 字段标识号(1) 5)规则 required: 该值必须设置 optional: 可以不设置,不设置则不会编码进去; 解码后是默认值 repeated: 字段可以重复任意多次(包括0次),类似于List、vector数组 6)数据类型 double float int32 sint32: 编码为负数时,比int32高效 int 64 sint64 fixed32: fixed64: sfixed32: sfixed64: bool: utf-8 或 7-bit ascii string: bytes: 7)每次定义完一个数据成员,以分号结尾 8)枚举 enum Direction { START = 0; EAST = 1; SOUTH = 2; WEST = 3; NORTH = 4; }; 9)包: 防止不同消息类型,存在命名冲突。 c/c++是名字空间 package test; 10)message的嵌套使用 message address_book { repeated myperson persons = 1; // 人物联系表 } 11)proto3与proto2的区别 (1)移除required λ protoc.exe --cpp_out=./ test3.proto test3.proto:16:18: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default. (2)optional改为singular(也去掉) (3)移除了default选项。proto3中,字段的默认值只能根据字段类型由系统决定 (4)枚举类型的第一个字段必须为0 λ protoc.exe --cpp_out=./ test3.proto test3.proto: The first enum value must be zero in proto3. 12)proto2 syntax = "proto2"; package test; enum Direction { START = 0; EAST = 1; SOUTH = 2; WEST = 3; NORTH = 4; }; message myperson { // 消息开始 required string name = 1; required int32 age = 2; optional int32 sex = 3; repeated uint32 array_value = 4; } // 消息结束 message address_book { repeated myperson persons = 1; // 人物联系表 } 13)proto3 syntax = "proto3"; package test; enum Direction { EAST = 1; SOUTH = 2; WEST = 3; NORTH = 4; }; message myperson { // 消息开始 string name = 1; int32 age = 2; int32 sex = 3; repeated uint32 array_value = 4; } // 消息结束 message address_book { repeated myperson persons = 1; // 人物联系表 }
C# 使用protobuf序列化反序列化数据
参考:https://www.cnblogs.com/luludongxu/p/17952865
https://www.cnblogs.com/Dotnet9-com/p/12052131.html
C# 中使用 Protocol Buffers 協定來序列化與反序列化物件
https://blog.yowko.com/csharp-protobuf-serialize-deserialize/
protobuf反序列化数据
var buffer = new byte[1024 * 4]; var result = new ArraySegment<byte>(buffer); var myMessage = MyMessage.Parser.ParseFrom(buffer.AsSpan(0, result.Count).ToArray());
或者
MyMessage t = new MyMessage(); byte[] data = new byte[t.CalculateSize()]; using (CodedOutputStream cos = new CodedOutputStream(data)) { t.WriteTo(cos); //data = cos.to.ToArray(); }
反序列化
MyMessaget = MyMessage.Parser.ParseFrom(data);