版权声明:本文为原创文章,转载请声明

近期在做一个棋牌项目,需要用到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.Serialize<IExtensible>(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 DeSerialize<T>(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.Deserialize<T>(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 = DeSerialize<Test>(bytes);6         Debug.Log(test2.test1 + test2.test2);7     }

输出结果 123456

附上protobuf-net.dll文件


预编译和转化工具

更多相关文章

  1. 克隆对象的方法实例教程
  2. C#开发微信门户及应用(二)之微信消息处理和应答的图文代码教程
  3. C#开发微信门户及应用(三)之文本消息和图文消息应答
  4. SignalR Self Host多端消息推送服务实例(三)
  5. SignalR Self Host多端消息推送服务介绍(二)
  6. c#中关于多线程创建对象的示例分享
  7. asp如何解析json字符串并转化为asp对象
  8. C#如何实现JSON与对象之间互相转换功能示例
  9. C#中匿名对象与var以及动态类型 dynamic的详解

随机推荐

  1. Android: Android Touch事件处理
  2. 转载 《Android程序运行过程,Android》
  3. lambda表达式介绍以及Android(安卓)Studi
  4. Android入门教程(二)之------搭建 Androi
  5. Android Map demo
  6. Android SDK Manager 的介绍
  7. Android热修复
  8. android 日期时间选择器
  9. Android AlertDialog ————单选对话框
  10. 隐藏菜单APP显示图标