C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信

2019-12-30 12:23:35于海丽
易采站长站为您分析C#使用Protocol Buffer(ProtoBuf)进行Unity的Socket通信的实例,Protocol Buffer是Google开发的数据格式,也是除了XML和JSON之外人气第三高的^^需要的朋友可以参考下  

首先来说一下本文中例子所要实现的功能:

  • 基于ProtoBuf序列化对象
  • 使用Socket实现时时通信
  • 数据包的编码和解码

    下面来看具体的步骤:

    一、Unity中使用ProtoBuf

    导入DLL到Unity中,
    创建网络传输的模型类:

    
    using System;
    using ProtoBuf;
    
    //添加特性,表示可以被ProtoBuf工具序列化
    [ProtoContract]
    public class NetModel {
     //添加特性,表示该字段可以被序列化,1可以理解为下标
     [ProtoMember(1)] 
     public int ID;
     [ProtoMember(2)]
     public string Commit;
     [ProtoMember(3)]
     public string Message;
    }
    
    using System;
    using ProtoBuf;
     
    //添加特性,表示可以被ProtoBuf工具序列化
    [ProtoContract]
    public class NetModel {
     //添加特性,表示该字段可以被序列化,1可以理解为下标
     [ProtoMember(1)] 
     public int ID;
     [ProtoMember(2)]
     public string Commit;
     [ProtoMember(3)]
     public string Message;
    }
    
    

    在Unity中添加测试脚本,介绍ProtoBuf工具的使用。

    
    using System;
    using System.IO;
    
    public class Test : MonoBehaviour {
    
     void Start () {
      //创建对象
      NetModel item = new NetModel(){ID = 1, Commit = "LanOu", Message = "Unity"};
      //序列化对象
      byte[] temp = Serialize(item);
      //ProtoBuf的优势一:小
      Debug.Log(temp.Length);
      //反序列化为对象
      NetModel result = DeSerialize(temp);
      Debug.Log(result.Message);
    
     }
    
     // 将消息序列化为二进制的方法
     // < param name="model">要序列化的对象< /param>
     private byte[] Serialize(NetModel model)
     {
      try {
       //涉及格式转换,需要用到流,将二进制序列化到流中
       using (MemoryStream ms = new MemoryStream()) {
        //使用ProtoBuf工具的序列化方法
        ProtoBuf.Serializer.Serialize<NetModel> (ms, model);
        //定义二级制数组,保存序列化后的结果
        byte[] result = new byte[ms.Length];
        //将流的位置设为0,起始点
        ms.Position = 0;
        //将流中的内容读取到二进制数组中
        ms.Read (result, 0, result.Length);
        return result;
       }
      } catch (Exception ex) {
       Debug.Log ("序列化失败: " + ex.ToString());
       return null;
      }
     }
    
     // 将收到的消息反序列化成对象
     // < returns>The serialize.< /returns>
     // < param name="msg">收到的消息.</param>
     private NetModel DeSerialize(byte[] msg)
     {
      try {
       using (MemoryStream ms = new MemoryStream()) {
        //将消息写入流中
        ms.Write (msg, 0, msg.Length);
        //将流的位置归0
        ms.Position = 0;
        //使用工具反序列化对象
        NetModel result = ProtoBuf.Serializer.Deserialize<NetModel> (ms);
        return result;
       }
      } catch (Exception ex) {  
        Debug.Log("反序列化失败: " + ex.ToString());
        return null;
      }
     }
    }
    
    using System;
    using System.IO;
     
    public class Test : MonoBehaviour {
     
     void Start () {
      //创建对象
      NetModel item = new NetModel(){ID = 1, Commit = "LanOu", Message = "Unity"};
      //序列化对象
      byte[] temp = Serialize(item);
      //ProtoBuf的优势一:小
      Debug.Log(temp.Length);
      //反序列化为对象
      NetModel result = DeSerialize(temp);
      Debug.Log(result.Message);
     
     }
     
     // 将消息序列化为二进制的方法
     // < param name="model">要序列化的对象< /param>
     private byte[] Serialize(NetModel model)
     {
      try {
       //涉及格式转换,需要用到流,将二进制序列化到流中
       using (MemoryStream ms = new MemoryStream()) {
        //使用ProtoBuf工具的序列化方法
        ProtoBuf.Serializer.Serialize<NetModel> (ms, model);
        //定义二级制数组,保存序列化后的结果
        byte[] result = new byte[ms.Length];
        //将流的位置设为0,起始点
        ms.Position = 0;
        //将流中的内容读取到二进制数组中
        ms.Read (result, 0, result.Length);
        return result;
       }
      } catch (Exception ex) {
       Debug.Log ("序列化失败: " + ex.ToString());
       return null;
      }
     }
     
     // 将收到的消息反序列化成对象
     // < returns>The serialize.< /returns>
     // < param name="msg">收到的消息.</param>
     private NetModel DeSerialize(byte[] msg)
     {
      try {
       using (MemoryStream ms = new MemoryStream()) {
        //将消息写入流中
        ms.Write (msg, 0, msg.Length);
        //将流的位置归0
        ms.Position = 0;
        //使用工具反序列化对象
        NetModel result = ProtoBuf.Serializer.Deserialize<NetModel> (ms);
        return result;
       }
      } catch (Exception ex) {  
        Debug.Log("反序列化失败: " + ex.ToString());
        return null;
      }
     }
    }