socket传输protobuf字节流实例教程
导读:收集整理的这篇文章主要介绍了socket传输protobuf字节流实例教程,觉得挺不错的,现在分享给大家,也给大家做个参考。版权声明:本文为原创文章,转载请声明 近期在做一个棋牌项目,需要用到socket传输PRotobuf字节流,在网上找...
收集整理的这篇文章主要介绍了socket传输protobuf字节流实例教程,觉得挺不错的,现在分享给大家,也给大家做个参考。版权声明:本文为原创文章,转载请声明 近期在做一个棋牌项目,需要用到socket传输PRotobuf字节流,在网上找了一些博客和文章后发现,没有特别全面的,所以把自己研究的全部源码拿出来和大家分享,因为刚开始做,可能会有不足的地方,欢迎拍砖~~
这一篇主要是protocol buffer文件的序列化和解析,废话不多说了,直接上干货
1 /// summary> 2 /// 将消息序列化为二进制的方法 3 /// /summary> 4 /// param name="model"> 要序列化的对象/param> 5 public static byte[] Serialize(IExtensible model) 6 { 7 try 8 { 9 //创建流对象10 MemoryStream ms = new MemoryStream()11 //使用ProtoBuf自带的序列化工具序列化IExtensible对象12 Serializer.SerializeIExtensible> (ms, model); 13 //创建二级制数组,保存序列化后的流14 byte[] bytes = new byte[ms.Length]; 15 //将流的位置设为016 ms.PosITion = 0; 17 //将流中的内容读取到二进制数组中18 ms.Read(bytes, 0, bytes.Length); 19 return bytes; 20 } 21 catch (Exception e)22 { 23 Debug.LOG("序列化失败: " + e.ToString()); 24 return null; 25 } 26 }
protobuf文件中的每一条message经过protocol buffer提供的ProtoGen工具可以转成c#的中的类,例如
message test { required string test1= 1; required string test2= 2; }
经过转化后就变成了
1 [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"SedReq")] 2 public partial class Test : global::ProtoBuf.IExtensible 3 { 4 public Test() { } 5 6 private string _test1; 7 [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"test1", DataFormat = global::ProtoBuf.DataFormat.Default)] 8 public string test1 9 { 10 get { return _test1; } 11 set { _test1 = value; } 12 } 13 private string _test2; 14 [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"test2", DataFormat = global::ProtoBuf.DataFormat.Default)]15 public string test216 { 17 get { return _test2; } 18 set { _test2 = value; } 19 } 20 private global::ProtoBuf.IExtension extensionObject; 21 global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createifMissing)22 { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } 23 }
无视所有带global的代码,你会发现,转化后的c#类和一个标准的c#实体类一模一样,并且,这些转化后的类都继承至ProtoBuf.IExtensible,所以上文中的序列化函数的参数的类型是IExtensible
有了序列化,当然还需要反序列化,也就是讲byte[]反序列化为继承至IExtensible的类型的对象
1 /// summary> 2 /// 将收到的消息反序列化成IExtensible对象 3 /// /summary> 4 /// param name="msg"> 收到的消息的字节流./param> 5 /// returns> /returns> 6 public static T DeSerializeT> (byte[] bytes) where T : IExtensible 7 { 8 try 9 { 10 MemoryStream ms = new MemoryStream()11 //将消息写入流中12 ms.Write(bytes, 0, bytes.Length); 13 //将流的位置归014 ms.Position = 0; 15 //反序列化对象16 T result = Serializer.DeserializeT> (ms); 17 return result; 18 } 19 catch (Exception e)20 { 21 Debug.Log("反序列化失败: " + e.ToString()); 22 return null; 23 } 24 }
因为反序列化后的对象是继承至IExtensible的类的对象,所以返回值必须使用泛型约束来定义,这样才能保证函数的通用性
工具搞定,接下来就是测试代码了
1 public void Test()2 { 3 Test test = new Test() { test1 = "123", test2 = "456" } ; 4 byte[] bytes = Serialize(test); 5 Test test2 = DeSerializeTest> (bytes); 6 Debug.Log(test2.test1 + test2.test2); 7 }
输出结果 123456
附上protobuf-net.dll文件
预编译和转化工具
以上就是socket传输protobuf字节流实例教程的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: socket传输protobuf字节流实例教程
本文地址: https://pptw.com/jishu/592281.html