当前位置:   article > 正文

【Unity】 在Unity中实现Tcp通讯(3)—— ProtoBuf_unity基于protobuf的网络通讯

unity基于protobuf的网络通讯

通过上两篇内容

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相关的讲解。

 

一.安装使用protobuf以及生成CSharp代码

1.安装 Python

下载python27,安装并添加系统变量

在命令行执行"python" 命令,出现下图表示安装成功

 

 

2.安装Protobuf

先在这里下载Protobuf,这是一个编译好的发布版本,如果想自己编译就下载源码即可,我用得是2.5.0

在目录Protobuf-2.5.0\python进入命令行,执行命令"python setup.py install"(进入到python路径然后shift+右键打开命令行即可)

出现下图则安装成功

 

3.下载Protobuf Net编译proto gen

这里下载Protobuf Net的源码,分别编译ProtoGen,precompile,protobuf-net这3个工程

 

将得到这些文件,把它们拷出来,放到和Protobuf同级目录下,这里放到了proto-gen-cs目录下

 

由于这个下载地址下载速度堪忧,这里给出编译好的版本,直接下载使用即可

 

4.编写bat程序,批量转换.proto文件

在Protobuf同级目录下创建一个空的txt,将其重命名为buildcs.bat(名字随意),如图

然后bat文件内输入这么一行代码,保存

  1. @echo off
  2. set Path=proto-gen-cs\protogen.exe
  3. for /f "delims=" %%i in ('dir  /b Proto "proto/*.proto"') do %Path% -i:proto/%%i -o:cs/%%~ni.cs
  4. pause

 

proto文件夹下创建测试proto协议,新建一个空txt,重命名为test.proto

使用pad++或者sublime之类的编辑器打开它,输入如下代码

  1. package client;
  2. message test {
  3. optional string content = 1; //name
  4. }

这里如果不了解proto协议如何编写可以看这篇文章

 

双击buildcs.bat不出以为,会在cs文件夹下得到一个转换后的csharp代码,长这个样子


 

二.使用生成的代码序列化数据,进行Tcp通讯

有了proto的代码,就可以将其导入到项目中使用。

1.客户端:

把protobuf-net.dll拖入到unity的plugins文件夹下,把生成的test.cs拖入到unity的scripts文件夹下

先封装一个工具类,它用于序列化和反序列化数据

  1. using System;
  2. using ProtoBuf;
  3. using System.IO;
  4. public class ProtoBufUtil
  5. {
  6. public static byte[] ObjectToBytes<T>(T instance)
  7. {
  8. try
  9. {
  10. byte[] array;
  11. if (instance == null)
  12. {
  13. array = new byte[0];
  14. }
  15. else
  16. {
  17. MemoryStream memoryStream = new MemoryStream();
  18. Serializer.Serialize(memoryStream, instance);
  19. array = new byte[memoryStream.Length];
  20. memoryStream.Position = 0L;
  21. memoryStream.Read(array, 0, array.Length);
  22. memoryStream.Dispose();
  23. }
  24. return array;
  25. }
  26. catch (Exception ex)
  27. {
  28. return new byte[0];
  29. }
  30. }
  31. public static T BytesToObject<T>(byte[] bytesData, int offset, int length)
  32. {
  33. if (bytesData.Length == 0)
  34. {
  35. return default(T);
  36. }
  37. try
  38. {
  39. MemoryStream memoryStream = new MemoryStream();
  40. memoryStream.Write(bytesData, 0, bytesData.Length);
  41. memoryStream.Position = 0L;
  42. T result = Serializer.Deserialize<T>(memoryStream);
  43. memoryStream.Dispose();
  44. return result;
  45. }
  46. catch (Exception ex)
  47. {
  48. return default(T);
  49. }
  50. }
  51. }

然后把在第二篇博客客中的客户端发送数据的代码改一下

  1. private void onClick()
  2. {
  3. if(!SocketMgr.Instance.IsConnected)
  4. {
  5. SocketMgr.Instance.Connect("127.0.0.1", 8888);
  6. return;
  7. }
  8. client.test sendContent = new client.test();//创建protobuf序列化实例
  9. sendContent.content = inputField.text;//对应字段赋值
  10. byte[] buffer = ProtoBufUtil.ObjectToBytes<test>(sendContent);//序列化
  11. SocketMgr.Instance.Send(1, buffer);//发送
  12. }

到这里,只要点击按钮,客户端会把数据序列化成protobuf的格式并发送到服务端

2.服务端:

添加对protobuf-net.dll(就是上面提到的那个protobuf-net.dll文件)的引用

把客户端的ProtobufUtil拖到服务端工程目录下,再把test.cs到也拖到工程目录下

然后把在第二篇博客客中的服务端解析数据的代码改一下

  1. private void CheckReceiveBuffer(object state)
  2. {
  3. lock (m_ReceiveQueue)
  4. {
  5. if (m_ReceiveQueue.Count < 1) return;
  6. byte[] buffer = m_ReceiveQueue.Dequeue();
  7. byte[] msgContent = new byte[buffer.Length - 2];
  8. ushort msgCode = 0;
  9. using (MemoryStream ms = new MemoryStream(buffer))
  10. {
  11. byte[] msgCodeBuffer = new byte[2];
  12. ms.Read(msgCodeBuffer, 0, msgCodeBuffer.Length);
  13. msgCode = BitConverter.ToUInt16(msgCodeBuffer, 0);
  14. ms.Read(msgContent, 0, msgContent.Length);
  15. }
  16. test content = ProtoBufUtil.BytesToObject<test>(msgContent, 0, msgContent.Length);//调用protobuf,把数据反序列化为test对象
  17. Console.WriteLine("消息编号:" + msgCode + ",内容:" + content.content);
  18. }
  19. }

到这里服务端也顺利的使用protobuf来解析数据了,下面开始测试

 

3.测试:

还是老套路,先启动服务器,然后客户端连接服务器,成功

 

然后客户端输入任意内容点击发送

服务端成功的使用Protobuf解析了数据,啪啪啪,此处仍然要有掌声雷动

 


 

三.结束

到这里protobuf的安装,使用就已经全部写完了,下一篇就开始进行心跳机制的讲解,各位再见!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/117968
推荐阅读
相关标签
  

闽ICP备14008679号