美文网首页unity网络征服Unity3d其他
Unity技术博客 - 基于ProtoBuf协议实现网络传输(上

Unity技术博客 - 基于ProtoBuf协议实现网络传输(上

作者: 肖马克_蛮牛 | 来源:发表于2016-01-20 11:12 被阅读6994次

    Unity版本: 5.3

    使用语言: C#


    写在前面

    ProtoBuf是Google公司推出的一种二进制序列化工具,适用于数据的网络传输。
    基于Socket实现时时通信,关于数据粘包的编码和解码处理是必不可少的。


    实现功能:

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

    1.Unity中使用ProtoBuf

    • 导入DLL到Unity中
    1. 创建网络传输的模型类

      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);
      
        }
      
        /// <summary>
        /// 将消息序列化为二进制的方法
        /// </summary>
        /// <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;
            }
        }
      
        /// <summary>
        /// 将收到的消息反序列化成对象
        /// </summary>
        /// <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;
                }
            }
        }
      

    写在最后

     #成功的道路没有捷径,代码这条路更是如此,唯有敲才是王道。

    相关文章

      网友评论

      • 斯樵: 非常👍赞!!! 看了很多protobuf的文章,终于这篇有用了!
        微巴特:https://purdyjotut.blogspot.jp/2013/10/using-protobuf-in-unity3d.html

      本文标题:Unity技术博客 - 基于ProtoBuf协议实现网络传输(上

      本文链接:https://www.haomeiwen.com/subject/dhclkttx.html