版权声明:本文为原创文章,转载请声明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字节流(一)的更多相关文章

  1. unity探索者之socket传输protobuf字节流(二)

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6977935.html 上一篇主要说的是protobuf字节流的序列化和解析,将pr ...

  2. unity探索者之socket传输protobuf字节流(四)

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7027659.html 上篇已经把socket的传输说的差不多了,这篇主要是说说断线 ...

  3. unity探索者之socket传输protobuf字节流(三)

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6986474.html 上一篇讲到了数据的处理,这一篇主要讲使用多线程收发消息 // ...

  4. C#使用ProtocolBuffer(ProtoBuf)进行Unity中的Socket通信

    首先来说一下本文中例子所要实现的功能: 基于ProtoBuf序列化对象 使用Socket实现时时通信 数据包的编码和解码 下面来看具体的步骤: 一.Unity中使用ProtoBuf 导入DLL到Uni ...

  5. Java 学习笔记 网络编程 使用Socket传输文件 CS模式

    Socket的简单认识 Socket是一种面向连接的通信协议,Socket应用程序是一种C/S(Client端/Server端)结构的应用程序 Socket是两台机器间通信的端点. Socket是连接 ...

  6. C++ socket 传输不同类型数据的四种方式

    使用socket传输组织好的不同类型数据,有四种不同的方式(我知道的嘿嘿): a. 结构体 b. Json序列化 c. 类对象 d. protobuf 下面逐一整理一下,方便以后进行项目开发. 1. ...

  7. [C#技术参考]Socket传输结构数据

    最近在做一个机器人项目,要实时的接收机器人传回的坐标信息,并在客户端显示当前的地图和机器人的位置.当然坐标的回传是用的Socket,用的是C++的结构体表示的坐标信息.但是C#不能像C++那样很eas ...

  8. Java使用Socket传输文件遇到的问题(转)

    1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...

  9. Java使用Socket传输文件遇到的问题

    1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...

随机推荐

  1. windows如何解决Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'

    问题再现与解读 首次,使用 java 命令+任意参数 都会报这个错误,最典型的就是java -version 解读一下这个报错信息,注册表路径 Software\JavaSoft\Java Runti ...

  2. LQB20180航班时间(sscanf)

    首先找找规律,两者相加除以二. 按格式读入sscanf 按格式输出printf("02d%",m);前导0 #include <iostream> #include & ...

  3. iOS 高效灵活地配置可复用视图组件的主题

      本文首发于 Ficow Shen's Blog,原文地址: iOS 高效灵活地配置可复用视图组件的主题.   内容概览 前言 如何配置主题? 如何更高效地配置主题? 面向协议/接口的方案     ...

  4. python爬虫基础要学什么,有哪些适合新手的书籍与教程?

    一,爬虫基础: 首先我们应该了解爬虫是个什么东西,而不是直接去学习带有代码的内容,新手小白应该花一个小时去了解爬虫是什么,再去学习带有代码的知识,这样所带来的收获是一定比你直接去学习代码内容要多很多很 ...

  5. PHP pclose() 函数

    定义和用法 pclose() 函数关闭由 popen() 打开的进程. 如果失败,该函数返回 FALSE. 语法 pclose(pipe) 参数 描述 pipe 必需.规定由 popen() 打开的进 ...

  6. PHP chop() 函数

    实例 移除字符串右侧的字符: <?php$str = "Hello World!";高佣联盟 www.cgewang.comecho $str . "<br& ...

  7. luogu P5667 拉格朗日插值2 拉格朗日插值 多项式多点求值 NTT

    LINK:P5667 拉格朗日插值2 给出了n个连续的取值的自变量的点值 求 f(m+1),f(m+2),...f(m+n). 如果我们直接把f这个函数给插值出来就变成了了多项式多点求值 这个难度好像 ...

  8. odoo12的视图常见属性和操作

    1.菜单视图属性: 常用属性: name是展示在用户界面中的菜单项标题 action是点击菜单项时运行的窗口操作的XML ID parent是父级菜单项的XML ID.本例中父级项由其它模块创建,因此 ...

  9. ubuntu18.04右键怎么添加新建空白文本文件

    安装好ubuntu18.04发现右键菜单中没有新建空白文件了,这样工作的时候需要创建文本文件就不是很方便了,这里我们就可以通过以下的方式把新建空白文件添加到右键 解决办法: 1.打开文件夹,在用户主目 ...

  10. 基于AspectCore打造属性注入

    前言 源自于晓晨在成都.net社区群的一篇文章 <晓晨的ASP.NET Core 奇淫技巧之伪属性注入> 他的思路是 Ioc容器替换 ControllerActivator,因为只能在控制 ...