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)休息一下就解决 ...
随机推荐
- jenkins集群(三) -- master和slave配置git
一.Linux(master)上安装git 1.运行命令:yum -y install git 2.git的默认安装目录是: 二.给Linux下Git配置好秘钥(公钥 + 私钥) 1.添加用户和密码 ...
- Java方法(函数)
4.1方法简介 方法是语句的集合,他们在一起执行一个功能: 1.方法是解决一类问题的步骤的有序组合(功能块) 2.方法包含于类与对象中 3.方法在程序中创建,在其它地方引用 4.原子性:单一职能原则( ...
- Python 简明教程 --- 26,Python 多进程编程
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 学编程最有效的方法是动手敲代码. 目录 1,什么是多进程 我们所写的Python 代码就是一个程序, ...
- integrator.java目录
integrater 目录d:\zixing\zxing-zxing-3.3.2\android-integration\src\main\java\com\google\zxing\integrat ...
- 记一次使用commit提交大文件无法推送到远程库解决问题过程及git rebase使用
记一次使用commit提交大文件无法推送到远程库解决问题过程及git rebase使用 目录 大文件无法push到远程仓库 问题 commit的大文件无法push到远程库解决办法 git filter ...
- Python os.lseek() 方法
概述 os.lseek() 方法用于设置文件描述符 fd 当前位置为 pos, how 方式修改.高佣联盟 www.cgewang.com 在Unix,Windows中有效. 语法 lseek()方法 ...
- PHP frenchtojd() 函数
------------恢复内容开始------------ 实例 把法国共和历法的日期转换为儒略日计数,然后再转换回法国共和历法的日期: <?php$jd=frenchtojd(3,3,14) ...
- 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖
LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...
- explain关键字使用解释
原文: 58沈剑 架构师之路 https://mp.weixin.qq.com/s/oWNrLHwqM-0ObuYbuGj98A <数据库允许空值,往往是悲剧的开始>一文通过explai ...
- [转]Java死锁排查
文章来源:微信公众号:猿天地 1. 死锁的概念: 是Java多线程情况下,两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象,若无外力作用,它们都讲无法推进下去.此时称 ...