赞
踩
通过上两篇内容
https://blog.csdn.net/s_GQY/article/details/106187350
https://blog.csdn.net/s_GQY/article/details/106192109
服务端和客户端的通讯已经实现了。
但是,在之前的通讯中是直接使用了字符串来进行数据的传输。
而在实际开发当中,要传输的数据结构是非常的复杂的,仅仅使用字符串势必无法满足基本的开发需求。
于是,本篇将来阐述一下Tcp网络通讯中常用的序列化工具,Protobuf。
Protobuf是Google研发的一种数据序列化工具,它使用Tag技术使数据在序列化成byte时变得非常的小,解析速度也是非常的快,所以很多软件、游戏的网络通讯部分通常都会采用Protobuf来进行数据的传输。
关于Tag技术及Protobuf原理这里不做过多的阐述,有兴趣可以看这篇文章
下面开始进行Protobuf相关的讲解。
下载python27,安装并添加系统变量
在命令行执行"python" 命令,出现下图表示安装成功
先在这里下载Protobuf,这是一个编译好的发布版本,如果想自己编译就下载源码即可,我用得是2.5.0
在目录Protobuf-2.5.0\python进入命令行,执行命令"python setup.py install"(进入到python路径然后shift+右键打开命令行即可)
出现下图则安装成功
从这里下载Protobuf Net的源码,分别编译ProtoGen,precompile,protobuf-net这3个工程
将得到这些文件,把它们拷出来,放到和Protobuf同级目录下,这里放到了proto-gen-cs目录下
由于这个下载地址下载速度堪忧,这里给出编译好的版本,直接下载使用即可
在Protobuf同级目录下创建一个空的txt,将其重命名为buildcs.bat(名字随意),如图
然后bat文件内输入这么一行代码,保存
- @echo off
-
- set Path=proto-gen-cs\protogen.exe
-
- for /f "delims=" %%i in ('dir /b Proto "proto/*.proto"') do %Path% -i:proto/%%i -o:cs/%%~ni.cs
-
- pause
proto文件夹下创建测试proto协议,新建一个空txt,重命名为test.proto
使用pad++或者sublime之类的编辑器打开它,输入如下代码
- package client;
-
- message test {
- optional string content = 1; //name
- }
这里如果不了解proto协议如何编写可以看这篇文章
双击buildcs.bat不出以为,会在cs文件夹下得到一个转换后的csharp代码,长这个样子
有了proto的代码,就可以将其导入到项目中使用。
把protobuf-net.dll拖入到unity的plugins文件夹下,把生成的test.cs拖入到unity的scripts文件夹下
先封装一个工具类,它用于序列化和反序列化数据
- using System;
- using ProtoBuf;
- using System.IO;
-
-
- public class ProtoBufUtil
- {
- public static byte[] ObjectToBytes<T>(T instance)
- {
- try
- {
- byte[] array;
- if (instance == null)
- {
- array = new byte[0];
- }
- else
- {
- MemoryStream memoryStream = new MemoryStream();
- Serializer.Serialize(memoryStream, instance);
- array = new byte[memoryStream.Length];
- memoryStream.Position = 0L;
- memoryStream.Read(array, 0, array.Length);
- memoryStream.Dispose();
- }
-
- return array;
-
- }
- catch (Exception ex)
- {
-
- return new byte[0];
- }
- }
-
- public static T BytesToObject<T>(byte[] bytesData, int offset, int length)
- {
- if (bytesData.Length == 0)
- {
- return default(T);
- }
- try
- {
- MemoryStream memoryStream = new MemoryStream();
- memoryStream.Write(bytesData, 0, bytesData.Length);
- memoryStream.Position = 0L;
- T result = Serializer.Deserialize<T>(memoryStream);
- memoryStream.Dispose();
- return result;
- }
- catch (Exception ex)
- {
- return default(T);
- }
- }
- }
然后把在第二篇博客客中的客户端发送数据的代码改一下
- private void onClick()
- {
- if(!SocketMgr.Instance.IsConnected)
- {
- SocketMgr.Instance.Connect("127.0.0.1", 8888);
- return;
- }
-
- client.test sendContent = new client.test();//创建protobuf序列化实例
- sendContent.content = inputField.text;//对应字段赋值
- byte[] buffer = ProtoBufUtil.ObjectToBytes<test>(sendContent);//序列化
- SocketMgr.Instance.Send(1, buffer);//发送
- }
到这里,只要点击按钮,客户端会把数据序列化成protobuf的格式并发送到服务端
添加对protobuf-net.dll(就是上面提到的那个protobuf-net.dll文件)的引用
把客户端的ProtobufUtil拖到服务端工程目录下,再把test.cs到也拖到工程目录下
然后把在第二篇博客客中的服务端解析数据的代码改一下
- private void CheckReceiveBuffer(object state)
- {
- lock (m_ReceiveQueue)
- {
- if (m_ReceiveQueue.Count < 1) return;
- byte[] buffer = m_ReceiveQueue.Dequeue();
- byte[] msgContent = new byte[buffer.Length - 2];
- ushort msgCode = 0;
-
- using (MemoryStream ms = new MemoryStream(buffer))
- {
- byte[] msgCodeBuffer = new byte[2];
- ms.Read(msgCodeBuffer, 0, msgCodeBuffer.Length);
- msgCode = BitConverter.ToUInt16(msgCodeBuffer, 0);
- ms.Read(msgContent, 0, msgContent.Length);
- }
-
- test content = ProtoBufUtil.BytesToObject<test>(msgContent, 0, msgContent.Length);//调用protobuf,把数据反序列化为test对象
- Console.WriteLine("消息编号:" + msgCode + ",内容:" + content.content);
- }
- }
到这里服务端也顺利的使用protobuf来解析数据了,下面开始测试
还是老套路,先启动服务器,然后客户端连接服务器,成功
然后客户端输入任意内容点击发送
服务端成功的使用Protobuf解析了数据,啪啪啪,此处仍然要有掌声雷动
到这里protobuf的安装,使用就已经全部写完了,下一篇就开始进行心跳机制的讲解,各位再见!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。