一、什么是ProtoBuf

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。它是一种类似于xml、json等类似作用的交互格式。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。

google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。

作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

随着移动市场的异军突起以及它自身的优点,PB最为一种数据交换格式彻底火了。

二、ProtoBuf的版本

PB具有三个版本:

  一、Google官方版本:https://github.com/google/protobuf/tree/master/csharp(谷歌官方开发、比较晦涩,主库名字:Google.ProtoBuf.dll)

  二、.Net社区版本:https://github.com/mgravell/protobuf-net(.Net社区爱好者开发,写法上比较符合.net上的语法习惯,主库名字:protobuf-net.dll)

  三、.Net社区版本(二):https://github.com/jskeet/protobuf-csharp-port(据说是由谷歌的.net员工为.net开发,在官方没有出来csharp的时候开发,到发博文时还在维护,主库名字:Google.ProtocolBuffers.dll)

至于选用那个版本,跨平台的需求不大的话,可以用版本二、大的话可以选用一或者三。(本文后续选用二为例)

三、ProtoBuf有什么用

  (1)制作网络通信协议。

  (2)数据的存储(序列化和反序列化),类似于xml、json等;

我们先来看(1)。PB可以利用一种语言(作者简称pb语言源码,文件后缀为.proto)转化为通信类(.cs文件,其他语言会生成相应的后缀文件,如.h,.cpp的)。在此过程中需要用protoc.exe命令行工具生成.bin,然后用

ProtoGen.exe生成.cs文件,至于怎么调用命令行,这里不再赘述。倒是可以把这三个文件(有的可能需要ProtoGen.exe.config)放到一个目录下,然后写一个命令行文件.bat直接生成。

  1. echo on
  2.  
  3. set Path=ProtoGen\protogen.exe
  4.  
  5. %Path% -i:Message.proto -o:OpenAPIModel\Message.cs
  6.  
  7. pause

注意:不同的版本命令行是不一样的。(如果嫌麻烦,可以自己手撸协议,本人就是这么干的,不过注意各修饰字段,不过手撸只适用于版本二,因为其他的写法生不一样,生成.cs文件的时候需要同时生成一些方法)

我的一个proto文件

  1. message Message
  2. {
  3. required string messageType=;//消息类型,约定link为建立连接消息,command为命令消息,file为文件,fileToClient为到客户端的文件
  4. optional string sourceIp=;
  5. optional string sourcePort=;
  6. optional string content=; //消息内容
  7. optional stirng fileName=;
  8. optional bytes bytes = ;//文件数组
  9. optional string other = ;//预留
  10. optional int32 fileTotalLength = ;//文件总长度
  11. optional int32 fileIndex = ; //当前传输的下标
  12. optional int32 fileTotalCount = ; //文件拆分总个数
  13.  
  14. }

我自己手撸的文件

  1. using ProtoBuf;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8.  
  9. namespace AndroidSocketTest
  10. {
  11. [ProtoContract]
  12. public class Message
  13. {
  14. [ProtoMember()]
  15. public string messageType { get; set; }
  16. [ProtoMember()]
  17. public string sourceIp { get; set; }
  18. [ProtoMember()]
  19. public string sourcePort { get; set; }
  20. [ProtoMember()]
  21. public string content { get; set; } //消息内容
  22. [ProtoMember()]
  23. public string fileName { get; set; }
  24. private byte[] _bytes = null;
  25. [global::ProtoBuf.ProtoMember(, IsRequired = false, Name = @"bytes", DataFormat = global::ProtoBuf.DataFormat.Default)]
  26. [global::System.ComponentModel.DefaultValue(null)]
  27. public byte[] bytes
  28. {
  29. get { return _bytes; }
  30. set { _bytes = value; }
  31. }
  32. [ProtoMember()]
  33. public string other { get; set; } //预留
  34. [ProtoMember()]
  35. public int fileTotalLength { get; set; } //文件总长度
  36. [ProtoMember()]
  37. public int fileIndex { get; set; } //文件当前段数
  38. [ProtoMember()]
  39. public int fileTotalCount{get;set; } //文件总片数
  40. }
  41.  
  42. public static class MessageHelp
  43. {
  44. // 将消息序列化为二进制的方法
  45. // < param name="model">要序列化的对象< /param>
  46. public static byte[] Serialize(Message model)
  47. {
  48. try
  49. {
  50. //涉及格式转换,需要用到流,将二进制序列化到流中
  51. using (MemoryStream ms = new MemoryStream())
  52. {
  53. //使用ProtoBuf工具的序列化方法
  54. ProtoBuf.Serializer.Serialize<Message>(ms, model);
  55. //定义二级制数组,保存序列化后的结果
  56. byte[] result = new byte[ms.Length];
  57. //将流的位置设为0,起始点
  58. ms.Position = ;
  59. //将流中的内容读取到二进制数组中
  60. ms.Read(result, , result.Length);
  61. return result;
  62. }
  63. }
  64. catch (Exception ex)
  65. {
  66. return null;
  67. }
  68. }
  69.  
  70. // 将收到的消息反序列化成对象
  71. // < returns>The serialize.< /returns>
  72. // < param name="msg">收到的消息.</param>
  73. public static Message DeSerialize(byte[] msg)
  74. {
  75. try
  76. {
  77. using (MemoryStream ms = new MemoryStream())
  78. {
  79. //将消息写入流中
  80. ms.Write(msg, , msg.Length);
  81. //将流的位置归0
  82. ms.Position = ;
  83. //使用工具反序列化对象
  84. Message result = ProtoBuf.Serializer.Deserialize<Message>(ms);
  85. return result;
  86. }
  87. }
  88. catch (Exception ex)
  89. {
  90. return null;
  91. }
  92. }
  93. }
  94. }

连下面的序列化和反序列化都写好了。

四、proto语法,引用一个同行的博客

http://blog.csdn.net/u014308482/article/details/52958148

有问题请加群沟通qq:568055323

.Net环境下调用ProtoBuf的更多相关文章

  1. C#多线程环境下调用 HttpWebRequest 并发连接限制

    C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...

  2. java 在centos6.5+eclipse环境下调用opencv实现sift算法

    java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core ...

  3. Windows环境下google protobuf入门

    我使用的是最新版本的protobuf(protobuf-2.6.1),编程工具使用VS2010.简单介绍下google protobuf: google protobuf 主要用于通讯,是google ...

  4. 【Tesseract-OCR】在VS2012环境下调用API方法---注意避免名字冲突

    由于在VS2012中使用OpenCV可以得到插件ImageWatch.vsix的支持,查看图像非常方便,所以一直想在VS2012环境下把Tesseract-OCR融合进来,但是这一错误折腾了我好久: ...

  5. 【转】C#多线程环境下调用 HttpWebRequest 并发连接限制

    .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows  7 下默认是2,在服务器操作 ...

  6. 多线程环境下调用 HttpWebRequest 并发连接限制

    .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows  7 下默认是2,在服务器操作 ...

  7. 非Linux环境下调用sh命令

    方法一:把cygwin的bin配置到环境变量里,这样做了以后在cmd.exe里也可以使用linux的命令 def exe_command(command): p = subprocess.Popen( ...

  8. [zz]C#多线程环境下调用 HttpWebRequest 并发连接限制

    .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows 7 下默认是2,在服务器操作系 ...

  9. spring-cloud-kubernetes服务发现之在k8s环境下开发spring cloud应用

    通常情况下,我们的线上的服务在迁移到k8s环境下的时候,都是采用平滑迁移的方案.服务治理与注册中心等都是采用原先的组件.比如spring cloud应用,在k8s环境下还是用原来的一套注册中心(如eu ...

随机推荐

  1. Java中的方法重载与方法重写

    重载(overload) 重载是在一个类中,同名方法拥有不同的参数列表则视为重载.不同的参数列表包括:参数数量不同,参数类型不同,参数顺序不同.重载对于返回类型没有要求,所以不能通过返回类型去判断是否 ...

  2. Mac下写博客工具MarsEdit相关资料

    参考资料: https://www.maoshu.cc/967.html 下载地址: https://www.red-sweater.com/marsedit/ 博客园的配置: http://www. ...

  3. Java岗 面试考点精讲(基础篇02期)

    1. 两个对象的hashCode相同,则equals也一定为true,对吗? 不对,答案见下面的代码: @Override public int hashCode() { return 1; } 两个 ...

  4. 使用Retrofit2+RxJava2+ProtoBuf实现网络请求

    引言 Retrofit 是一个用于 Android 和 Java 平台的类型安全的,底层使用OkHttp实现网络请求框架.Retrofit 通过将 API 抽象成 Java 接口而让我们连接到 RES ...

  5. 【 js 工具 】如何在Github Pages搭建自己写的页面?

    最近发现 github 改版了,已没有像原来的 Launch automatic page generator 这样的按钮等,所以我对我的文章也进行了修正,对于新版来说,步骤更加简单了.欢迎享用. - ...

  6. lnmp环境切换php版本,并安装相应redis扩展

    ubuntu+nginx+mysql+php+redis,其中php装两个版本,php7和php56 1.让nginx支持不同站点可以选择不同的php版本 1>创建fastcgi.conf文件 ...

  7. 2018-12-14 JavaScript实现ZLOGO: 前进方向和速度

    系列前文: JavaScript实现ZLOGO子集: 前进+转向 JavaScript实现ZLOGO子集: 单层循环功能 JavaScript实现ZLOGO子集: 测试用例 JavaScript实现Z ...

  8. 大数据时代,Wyn Enterprise和您一起探讨CIO的困境和出路 ZT

    这是一篇知识分享帖,如果您致力于成为一名CIO,希望您能够阅读完,信息虽然简略,但我们依然希望可以帮到您. CIO:首席信息官 CIO是干什么的 一.经典的CIO主要负责什么 1.IT战略规划.IT预 ...

  9. iOS ----------要学习的地方(链接整理)

    1.http://www.cocoachina.com/special/xcode/ 2.http://blog.csdn.net/a416863220/article/details/4111387 ...

  10. java8中Lambda表达式和Stream API

    一.Lambda表达式 1.语法格式 Lambda是匿名函数,可以传递代码.使用“->”操作符,改操作符将lambda分成两部分: 左侧:指定了 Lambda 表达式需要的所有参数 右侧:指定了 ...