配置文件:Plugins:protobuf-net.dll

具体脚本如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// 编码和解码
/// </summary>
public class NetEncode
{
    /// <summary>
    /// 将数据编码 长度+内容
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public static byte[] Encode(byte[] data)
    {
        //整型占4个字节,所以声明一个+4的数组
        byte[] result = new byte[data.Length + 4];
        //使用流将编码二进制
        MemoryStream ms = new MemoryStream();
        BinaryWriter br = new BinaryWriter(ms);
        br.Write(data.Length);
        br.Write(data);
        //将流中的内容复制到数组中
        Buffer.BlockCopy(ms.ToArray(), 0, result, 0, (int)ms.Length);
        br.Close();
        ms.Close();
        return result;
    }

    /// <summary>
    /// 将数据解码
    /// </summary>
    /// <param name="cahce"></param>
    /// <returns></returns>
    public static byte[] Decode(ref List<byte> cahce)
    {
        //首先获取到长度,整型4字节,如果字节数不足4字节,舍弃
        if (cahce.Count < 4)
        {
            return null;
        }
        //读取数据
        MemoryStream ms = new MemoryStream(cahce.ToArray());
        BinaryReader br = new BinaryReader(ms);
        //先读取出包头的长度
        int len = br.ReadInt32();
        //根据长度,判断内容是否传递完毕
        if (len > ms.Length - ms.Position)
        {
            return null;
        }
        //获取数据
        byte[] result = br.ReadBytes(len);
        //清空消息池
        cahce.Clear();
        //将剩余没有处理的消息重新存入消息池中
        cahce.AddRange(br.ReadBytes((int)ms.Length - (int)ms.Position));
        return result;
    }
}
using System.Collections;
using System.Collections.Generic;
using ProtoBuf;
using UnityEngine;

//添加特性,表示可以被ProtoBuf工具序列化
[ProtoContract]
public class NetModel
{

    //添加特性,表示字段可以被序列化,1可以理解为下标
    [ProtoMember(1)] public int ID;
    [ProtoMember(2)] public string Commit;
    [ProtoMember(3)] public string Message;

}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public static class NetSerilizer
{

    /// <summary>
    /// 将消息序列化为二进制数组
    /// </summary>
    /// <param name="netModel"></param>
    /// <returns></returns>
    public static byte[] Serialize(NetModel netModel)
    {
        try
        {
            //将二进制序列化到流中
            using (MemoryStream ms = new MemoryStream())
            {
                //使用ProtoBuf工具序列化方法
                ProtoBuf.Serializer.Serialize<NetModel>(ms, netModel);
                //保存序列化后的结果
                byte[] result = new byte[ms.Length];
                //将流的位置设置为0,起始点
                ms.Position = 0;
                //将流中的内容读取到二进制数组中
                ms.Read(result, 0, result.Length);
                return result;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    /// <summary>
    /// 把收到的消息反序列化成对象
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static NetModel DeSerialize(byte[] msg)
    {
        try
        {
            using (MemoryStream ms = new MemoryStream())
            {
                //将消息写入流中
                ms.Write(msg, 0, msg.Length);
                //将流的位置归零
                ms.Position = 0;
                //使用工具反序列化对象
                NetModel result = ProtoBuf.Serializer.Deserialize<NetModel>(ms);
                return result;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;


/// <summary>
/// 模拟客户端操作
/// </summary>
public class NetUserToken
{
    /// <summary>
    /// 用于连接的socket
    /// </summary>
    private Socket socket;
    /// <summary>
    /// 数据缓冲区
    /// </summary>
    public byte[] byteBuff;
    /// <summary>
    /// 每次接受和发送的数据大小
    /// </summary>
    private readonly int size = 1024;
    /// <summary>
    /// 接收数据池
    /// </summary>
    private List<byte> receiveCache;

    private bool isReceiving;
    /// <summary>
    /// 发送数据池
    /// </summary>
    private Queue<byte[]> sendCache;

    private bool isSending;
    /// <summary>
    /// 接收到消息后的回调
    /// </summary>
    private Action<NetModel> receiveCallback;


    public NetUserToken()
    {
        byteBuff = new byte[size];
        receiveCache = new List<byte>();
        sendCache = new Queue<byte[]>();
    }

    /// <summary>
    /// 服务器接收客户端发送的消息
    /// </summary>
    /// <param name="data"></param>
    public void Receive(byte[] data)
    {
        Debug.Log("接收数据");
        //将接收到的数据放入数据池中
        receiveCache.AddRange(data);
        //如果没在读数据
        if (!isReceiving)
        {
            isReceiving = true;

        }
    }

    /// <summary>
    /// 读取数据
    /// </summary>
    private void ReadData()
    {
        byte[] data = NetEncode.Decode(ref receiveCache);

        //如果数据读取成功
        if (null != data)
        {
            NetModel item = NetSerilizer.DeSerialize(data);
            Debug.Log(item.ID + "," + item.Commit + "," + item.Message);
            if (null != receiveCallback)
            {
                receiveCallback(item);
            }
            //尾递归,继续处理数据
            ReadData();
        }
        else
        {
            isReceiving = false;
        }
    }

    /// <summary>
    /// 服务器发送消息给客户端
    /// </summary>
    private void Send()
    {
        try
        {
            if (sendCache.Count == 0)
            {
                isSending = false;
                return;
            }
            byte[] data = sendCache.Dequeue();
            int count = data.Length / size;
            int len = size;
            for (int i = 0; i < count + 1; i++)
            {
                if (i == count)
                {
                    len = data.Length - i * size;
                }
                socket.Send(data, i * size, len, SocketFlags.None);
            }
            Debug.Log("发送成功");
            Send();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    public void WriteSendData(byte[] data)
    {
        sendCache.Enqueue(data);
        if (!isSending)
        {
            isSending = true;
            Send();
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class PBTest : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {

        //创建对象
        NetModel item = new NetModel() { ID = 1, Commit = "马三", Message = "Unity" };
        //序列化对象
        byte[] temp = Serialize(item);
        Debug.Log("序列化数组长度:" + temp.Length);
        //反序列化为对象
        NetModel result = DeSerialize(temp);
        Debug.Log(result.ID + "," + result.Commit + "," + result.Message);
    }

    /// <summary>
    /// 将消息序列化为二进制数组
    /// </summary>
    /// <param name="netModel"></param>
    /// <returns></returns>
    private byte[] Serialize(NetModel netModel)
    {
        try
        {
            //将二进制序列化到流中
            using (MemoryStream ms = new MemoryStream())
            {
                //使用ProtoBuf工具序列化方法
                ProtoBuf.Serializer.Serialize<NetModel>(ms, netModel);
                //保存序列化后的结果
                byte[] result = new byte[ms.Length];
                //将流的位置设置为0,起始点
                ms.Position = 0;
                //将流中的内容读取到二进制数组中
                ms.Read(result, 0, result.Length);
                return result;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

    /// <summary>
    /// 把收到的消息反序列化成对象
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    private NetModel DeSerialize(byte[] msg)
    {
        try
        {
            using (MemoryStream ms = new MemoryStream())
            {
                //将消息写入流中
                ms.Write(msg, 0, msg.Length);
                //将流的位置归零
                ms.Position = 0;
                //使用工具反序列化对象
                NetModel result = ProtoBuf.Serializer.Deserialize<NetModel>(ms);
                return result;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}