Skip to content

Commit 9d0fa39

Browse files
committed
Protobuf练习
1 parent 97c9e6b commit 9d0fa39

35 files changed

+589
-0
lines changed

ProtoBufDemo/Assets/Plugins.meta

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
188 KB
Binary file not shown.

ProtoBufDemo/Assets/Plugins/protobuf-net.dll.meta

+25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ProtoBufDemo/Assets/Scene.meta

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ProtoBufDemo/Assets/Scene/main.unity

13 KB
Binary file not shown.

ProtoBufDemo/Assets/Scene/main.unity.meta

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ProtoBufDemo/Assets/Scripts.meta

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using UnityEngine;
6+
7+
/// <summary>
8+
/// 编码和解码
9+
/// </summary>
10+
public class NetEncode
11+
{
12+
/// <summary>
13+
/// 将数据编码 长度+内容
14+
/// </summary>
15+
/// <param name="data"></param>
16+
/// <returns></returns>
17+
public static byte[] Encode(byte[] data)
18+
{
19+
//整型占4个字节,所以声明一个+4的数组
20+
byte[] result = new byte[data.Length + 4];
21+
//使用流将编码二进制
22+
MemoryStream ms = new MemoryStream();
23+
BinaryWriter br = new BinaryWriter(ms);
24+
br.Write(data.Length);
25+
br.Write(data);
26+
//将流中的内容复制到数组中
27+
Buffer.BlockCopy(ms.ToArray(), 0, result, 0, (int)ms.Length);
28+
br.Close();
29+
ms.Close();
30+
return result;
31+
}
32+
33+
/// <summary>
34+
/// 将数据解码
35+
/// </summary>
36+
/// <param name="cahce"></param>
37+
/// <returns></returns>
38+
public static byte[] Decode(ref List<byte> cahce)
39+
{
40+
//首先获取到长度,整型4字节,如果字节数不足4字节,舍弃
41+
if (cahce.Count < 4)
42+
{
43+
return null;
44+
}
45+
//读取数据
46+
MemoryStream ms = new MemoryStream(cahce.ToArray());
47+
BinaryReader br = new BinaryReader(ms);
48+
//先读取出包头的长度
49+
int len = br.ReadInt32();
50+
//根据长度,判断内容是否传递完毕
51+
if (len > ms.Length - ms.Position)
52+
{
53+
return null;
54+
}
55+
//获取数据
56+
byte[] result = br.ReadBytes(len);
57+
//清空消息池
58+
cahce.Clear();
59+
//将剩余没有处理的消息重新存入消息池中
60+
cahce.AddRange(br.ReadBytes((int)ms.Length - (int)ms.Position));
61+
return result;
62+
}
63+
}

ProtoBufDemo/Assets/Scripts/NetEncode.cs.meta

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using ProtoBuf;
4+
using UnityEngine;
5+
6+
//添加特性,表示可以被ProtoBuf工具序列化
7+
[ProtoContract]
8+
public class NetModel
9+
{
10+
11+
//添加特性,表示字段可以被序列化,1可以理解为下标
12+
[ProtoMember(1)] public int ID;
13+
[ProtoMember(2)] public string Commit;
14+
[ProtoMember(3)] public string Message;
15+
16+
}

ProtoBufDemo/Assets/Scripts/NetModel.cs.meta

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using UnityEngine;
6+
7+
public static class NetSerilizer
8+
{
9+
10+
/// <summary>
11+
/// 将消息序列化为二进制数组
12+
/// </summary>
13+
/// <param name="netModel"></param>
14+
/// <returns></returns>
15+
public static byte[] Serialize(NetModel netModel)
16+
{
17+
try
18+
{
19+
//将二进制序列化到流中
20+
using (MemoryStream ms = new MemoryStream())
21+
{
22+
//使用ProtoBuf工具序列化方法
23+
ProtoBuf.Serializer.Serialize<NetModel>(ms, netModel);
24+
//保存序列化后的结果
25+
byte[] result = new byte[ms.Length];
26+
//将流的位置设置为0,起始点
27+
ms.Position = 0;
28+
//将流中的内容读取到二进制数组中
29+
ms.Read(result, 0, result.Length);
30+
return result;
31+
}
32+
}
33+
catch (Exception e)
34+
{
35+
Console.WriteLine(e);
36+
throw;
37+
}
38+
}
39+
40+
/// <summary>
41+
/// 把收到的消息反序列化成对象
42+
/// </summary>
43+
/// <param name="msg"></param>
44+
/// <returns></returns>
45+
public static NetModel DeSerialize(byte[] msg)
46+
{
47+
try
48+
{
49+
using (MemoryStream ms = new MemoryStream())
50+
{
51+
//将消息写入流中
52+
ms.Write(msg, 0, msg.Length);
53+
//将流的位置归零
54+
ms.Position = 0;
55+
//使用工具反序列化对象
56+
NetModel result = ProtoBuf.Serializer.Deserialize<NetModel>(ms);
57+
return result;
58+
}
59+
}
60+
catch (Exception e)
61+
{
62+
Console.WriteLine(e);
63+
throw;
64+
}
65+
}
66+
}

ProtoBufDemo/Assets/Scripts/NetSerilizer.cs.meta

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Net.Sockets;
5+
using UnityEngine;
6+
7+
8+
/// <summary>
9+
/// 模拟客户端操作
10+
/// </summary>
11+
public class NetUserToken
12+
{
13+
/// <summary>
14+
/// 用于连接的socket
15+
/// </summary>
16+
private Socket socket;
17+
/// <summary>
18+
/// 数据缓冲区
19+
/// </summary>
20+
public byte[] byteBuff;
21+
/// <summary>
22+
/// 每次接受和发送的数据大小
23+
/// </summary>
24+
private readonly int size = 1024;
25+
/// <summary>
26+
/// 接收数据池
27+
/// </summary>
28+
private List<byte> receiveCache;
29+
30+
private bool isReceiving;
31+
/// <summary>
32+
/// 发送数据池
33+
/// </summary>
34+
private Queue<byte[]> sendCache;
35+
36+
private bool isSending;
37+
/// <summary>
38+
/// 接收到消息后的回调
39+
/// </summary>
40+
private Action<NetModel> receiveCallback;
41+
42+
43+
public NetUserToken()
44+
{
45+
byteBuff = new byte[size];
46+
receiveCache = new List<byte>();
47+
sendCache = new Queue<byte[]>();
48+
}
49+
50+
/// <summary>
51+
/// 服务器接收客户端发送的消息
52+
/// </summary>
53+
/// <param name="data"></param>
54+
public void Receive(byte[] data)
55+
{
56+
Debug.Log("接收数据");
57+
//将接收到的数据放入数据池中
58+
receiveCache.AddRange(data);
59+
//如果没在读数据
60+
if (!isReceiving)
61+
{
62+
isReceiving = true;
63+
64+
}
65+
}
66+
67+
/// <summary>
68+
/// 读取数据
69+
/// </summary>
70+
private void ReadData()
71+
{
72+
byte[] data = NetEncode.Decode(ref receiveCache);
73+
74+
//如果数据读取成功
75+
if (null != data)
76+
{
77+
NetModel item = NetSerilizer.DeSerialize(data);
78+
Debug.Log(item.ID + "," + item.Commit + "," + item.Message);
79+
if (null != receiveCallback)
80+
{
81+
receiveCallback(item);
82+
}
83+
//尾递归,继续处理数据
84+
ReadData();
85+
}
86+
else
87+
{
88+
isReceiving = false;
89+
}
90+
}
91+
92+
/// <summary>
93+
/// 服务器发送消息给客户端
94+
/// </summary>
95+
private void Send()
96+
{
97+
try
98+
{
99+
if (sendCache.Count == 0)
100+
{
101+
isSending = false;
102+
return;
103+
}
104+
byte[] data = sendCache.Dequeue();
105+
int count = data.Length / size;
106+
int len = size;
107+
for (int i = 0; i < count + 1; i++)
108+
{
109+
if (i == count)
110+
{
111+
len = data.Length - i * size;
112+
}
113+
socket.Send(data, i * size, len, SocketFlags.None);
114+
}
115+
Debug.Log("发送成功");
116+
Send();
117+
}
118+
catch (Exception e)
119+
{
120+
Console.WriteLine(e);
121+
throw;
122+
}
123+
}
124+
125+
public void WriteSendData(byte[] data)
126+
{
127+
sendCache.Enqueue(data);
128+
if (!isSending)
129+
{
130+
isSending = true;
131+
Send();
132+
}
133+
}
134+
}

ProtoBufDemo/Assets/Scripts/NetUserToken.cs.meta

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)