unity探索者之socket传输protobuf字节流(一)
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6974229.html
近期在做一个棋牌项目,需要用到socket传输protobuf字节流,在网上找了一些博客和文章后发现,没有特别全面的,所以把自己研究的全部源码拿出来和大家分享,因为刚开始做,可能会有不足的地方,欢迎拍砖~~
这一篇主要是protocol buffer文件的序列化和解析,废话不多说了,直接上干货
/// <summary>
/// 将消息序列化为二进制的方法
/// </summary>
/// <param name="model">要序列化的对象</param>
public static byte[] Serialize(IExtensible model)
{
try
{
//创建流对象
MemoryStream ms = new MemoryStream()
//使用ProtoBuf自带的序列化工具序列化IExtensible对象
Serializer.Serialize<IExtensible>(ms, model);
//创建二级制数组,保存序列化后的流
byte[] bytes = new byte[ms.Length];
//将流的位置设为0
ms.Position = ;
//将流中的内容读取到二进制数组中
18 ms.Read(bytes, , bytes.Length);
return bytes;
}
catch (Exception e)
{
Debug.Log("序列化失败: " + e.ToString());
return null;
}
}
protobuf文件中的每一条message经过protocol buffer提供的ProtoGen工具可以转成c#的中的类,例如
message Test {
required string test1= ;
required string test2= ;
}
经过转化后就变成了
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"SedReq")]
public partial class Test : global::ProtoBuf.IExtensible
{
public Test() {} private string _test1;
[global::ProtoBuf.ProtoMember(, IsRequired = true, Name=@"test1", DataFormat = global::ProtoBuf.DataFormat.Default)]
public string test1
{
get { return _test1; }
set { _test1 = value; }
}
private string _test2;
[global::ProtoBuf.ProtoMember(, IsRequired = true, Name=@"test2", DataFormat = global::ProtoBuf.DataFormat.Default)]
public string test2
{
get { return _test2; }
set { _test2 = value; }
}
private global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
}
无视所有带global的代码,你会发现,转化后的c#类和一个标准的c#实体类一模一样,并且,这些转化后的类都继承至ProtoBuf.IExtensible,所以上文中的序列化函数的参数的类型是IExtensible
有了序列化,当然还需要反序列化,也就是讲byte[]反序列化为继承至IExtensible的类型的对象
/// <summary>
/// 将收到的消息反序列化成IExtensible对象
/// </summary>
/// <param name="msg">收到的消息的字节流.</param>
/// <returns></returns>
public static T DeSerialize<T>(byte[] bytes) where T : IExtensible
{
try
{
MemoryStream ms = new MemoryStream()
//将消息写入流中
ms.Write(bytes, , bytes.Length);
//将流的位置归0
ms.Position = ;
//反序列化对象
T result = Serializer.Deserialize<T>(ms);
return result;
}
catch (Exception e)
{
Debug.Log("反序列化失败: " + e.ToString());
return null;
}
}
因为反序列化后的对象是继承至IExtensible的类的对象,所以返回值必须使用泛型约束来定义,这样才能保证函数的通用性
工具搞定,接下来就是测试代码了
public void Test()
{
Test test = new Test() { test1 = "", test2 = "" };
byte[] bytes = Serialize(test);
Test test2 = DeSerialize<Test>(bytes);
Debug.Log(test2.test1 + test2.test2);
}
输出结果 123456
附上protobuf-net.dll文件
http://files.cnblogs.com/files/unityExplorer/protobuf-net.zip
预编译和转化工具
http://files.cnblogs.com/files/unityExplorer/protoGen.zip
unity探索者之socket传输protobuf字节流(一)的更多相关文章
- unity探索者之socket传输protobuf字节流(二)
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6977935.html 上一篇主要说的是protobuf字节流的序列化和解析,将pr ...
- unity探索者之socket传输protobuf字节流(四)
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7027659.html 上篇已经把socket的传输说的差不多了,这篇主要是说说断线 ...
- unity探索者之socket传输protobuf字节流(三)
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6986474.html 上一篇讲到了数据的处理,这一篇主要讲使用多线程收发消息 // ...
- C#使用ProtocolBuffer(ProtoBuf)进行Unity中的Socket通信
首先来说一下本文中例子所要实现的功能: 基于ProtoBuf序列化对象 使用Socket实现时时通信 数据包的编码和解码 下面来看具体的步骤: 一.Unity中使用ProtoBuf 导入DLL到Uni ...
- Java 学习笔记 网络编程 使用Socket传输文件 CS模式
Socket的简单认识 Socket是一种面向连接的通信协议,Socket应用程序是一种C/S(Client端/Server端)结构的应用程序 Socket是两台机器间通信的端点. Socket是连接 ...
- C++ socket 传输不同类型数据的四种方式
使用socket传输组织好的不同类型数据,有四种不同的方式(我知道的嘿嘿): a. 结构体 b. Json序列化 c. 类对象 d. protobuf 下面逐一整理一下,方便以后进行项目开发. 1. ...
- [C#技术参考]Socket传输结构数据
最近在做一个机器人项目,要实时的接收机器人传回的坐标信息,并在客户端显示当前的地图和机器人的位置.当然坐标的回传是用的Socket,用的是C++的结构体表示的坐标信息.但是C#不能像C++那样很eas ...
- Java使用Socket传输文件遇到的问题(转)
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
- Java使用Socket传输文件遇到的问题
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
随机推荐
- vue学习(八) vue中样式 class 定义引用
//style<style> .red{ color:red; } .thin{//字体粗细 font-weight:200 } .italic{//字体倾斜 font-style:ita ...
- fiddler替换修改后的js文件绕过无限debugger
转自:https://www.jianshu.com/p/38c4afae636c 1.在js文件右击, 然后点击save as ..., 把js文件保存到本地.(网站:https://taodaxi ...
- sed打印包含一个字符串的行到包含另一个字符串的行解答
sed -n '/字符串1/,/字符串2/p' filename 这个命令为什么有时候打印不出来想要的东西,例如:sed -n '/root/,/adm/p' /etc/passwd 我 ...
- shell 十三问
经典的Shell十三问 摘选整理自:http://bbs.chinaunix.net/thread-218853-1-1.htmlhttps://github.com/wzb56/13_questio ...
- 部署SpringBoot到阿里云
目录 安装Mysql 1. 下载命令 2. 进行repo的安装: 3. 安装mysql 部署SpringBoot到阿里云服务器 1.IDEA下载插件 2.进入 Preference 配置一个 Acce ...
- 02_Linux实操篇
第五章 VI和VIM编辑器 5.1. VI和VIM基本介绍 Vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器.由于对Unix及Linux系统的任何版本,Vi ...
- Rsync服务详解
Rsync简介 什么是rsync? Rsync是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具.Rstync软件适用于unix/linux/windows等多种操作系 ...
- Excel绘制经典图表
1.柱形图 2.条形图 3.饼图---复合饼图 4.圆环图 5.组合图 设置不同的纵轴 6.漏斗图 其中:合计呈逐渐下降的趋势,可以用漏斗图进行展示! 绘制漏斗图首先需要构建辅助列,在插入图形的时候选 ...
- PHP jdtogregorian() 函数
------------恢复内容开始------------ 实例 把格利高里历法的日期转换为儒略日计数,然后再转换回格利高里历法的日期: <?php$jd=gregoriantojd(6,20 ...
- PHP sleep() 函数
实例 延迟执行当前脚本 5 秒: <?phpecho date('h:i:s') . "<br>"; //sleep for 5 secondssleep(5); ...