• 【通信框架】Google的开源通信框架protobuf概述


    在阅读的过程中有不论什么问题,欢迎一起交流

    邮箱:1494713801@qq.com   

    QQ:1494713801

     

    一、作用

          protobuf(Protocol Buffers)是Google内部使用的一个项目,后来贡献给开源社区为大家使用。它要做的事情和xml类似。就是要把某种数据结构的信息有某种格式保存起来,主要用于数据存储、传输协议格式等场合。

    二、长处

         和xml有着类似的功能。那么肯定有一些更加优势的地方。

         1、时间开销

              xml格式化(序列化)的开销还能够,可是xml解析(反序列化)的开销较大。相比protobuf的时间开销要小一些;

          2、空间开销

             为了提高可读性xml中引入了一些冗余的文本信息,空间开销加大。相比protobuf的空间开销要小一些;

          3、开发调用简单

             仅仅需使用message定义消息结构。在发送方使用set方法发送消息,在接收方使用调用方法接收消息就可以。

    省去了xml配置、编译和解析的过程。

             比方:

    有个电子商务的系统(如果用C++实现),当中的模块A须要发送大量的订单信息给模块B,通讯的方式使用socket。


    如果订单包含例如以下属性:
    --------------------------------
      时间:time(用整数表示)
      客户id:userid(用整数表示)
      交易金额:price(用浮点数表示)
      交易的描写叙述:desc(用字符串表示)
    --------------------------------
      假设使用protobuf实现。首先要写一个proto文件(最好还是叫Order.proto),在该文件里加入一个名为"Order"的message结构。用来描写叙述通讯协议中的结构化数据。该文件的内容大致例如以下:


    --------------------------------
    message Order
    {
      required int32 time = 1;
      required int32 userid = 2;
      required float price = 3;
      optional string desc = 4;
    }
    --------------------------------

      然后,使用protobuf内置的编译器编译 该proto。因为本样例的模块是C++。你能够通过protobuf编译器的命令行參数(看“这里 ”),指定它生成C++语言的“订单包装类”。

    (一般来说,一个message结构会生成一个包装类)
      然后你使用类似以下的代码来序列化/解析该订单包装类:


    --------------------------------
    // 发送方
    Order order;
    order.set_time(XXXX);
    order.set_userid(123);
    order.set_price(100.0f);
    order.set_desc("a test order");

    string sOrder;
    order.SerailzeToString(&sOrder);
    // 然后调用某种socket的通讯库把序列化之后的字符串发送出去
    // ......

    --------------------------------
    // 接收方
    string sOrder;
    // 先通过网络通讯库接收到数据。存放到某字符串sOrder
    // ......

    Order order;
    if(order.ParseFromString(sOrder)) // 解析该字符串
    {
      cout << "userid:" << order.userid() << endl
      << "desc:" << order.desc() << endl;
    }
    else
    {
      cerr << "parse error!" << endl;
    }
    --------------------------------

          4、代码灵活,减少模块间的耦合性

            A和B两个模块相互通信。当当中一个模块或消息格式发生改变时,仅仅需修改一点代码就可以。

          5、支持多种编程语言

            Google公布的源代码中包含C++、Java、Python三种语言。如今能够支持ActionScript、C#、Lisp、Erlang、Perl、PHP、Ruby等。并且Protobuf支持通信的两方使用不同的语言开发。

    三、缺点

          1、代码可读性差

             Protobuf使用二进制格式进行编码,假设通信两方有一方出现了问题,二进制的消息非常难被读懂,非常难对错误定位。

    尽管Protobuf提供了TextFormat工具类,可是也不能彻底解决这个问题。未解决这个问题能够直接抓包并dump成log以定位错误。

          2、缺乏自描写叙述

             没有自描写叙述信息,二进制的格式非常难被看懂,需配合Proto文件。

    四、Protobuf的使用及实例

    1 下载安装

    (1)下载

    须要两个包。protobuf-2.5.0.tar.gz,protoc-2.5.0-win32.zip。

    本来能够到https://code.google.com/p/protobuf/downloads/list下载。只是被墙了。

    能够移步到这里下载:http://download.csdn.net/detail/erli11/7408633 

    下载同样版本号供java使用的protobuf-java-2.5.0.jar:

    http://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/2.5.0/protobuf-java-2.5.0.jar

    2demo展示

    (1)创建proto文件

    在protoc-2.5.0-win32文件夹(包括protoc.ext可运行文件),创建msg.proto

    1. package discover;  
    2. option java_package = "com.sg.discover";  
    3. option java_outer_classname = "SocialRecommend";    
    4.   
    5. message RecommendInfo  {  
    6.     optional string hid = 1;  
    7.     optional string tags = 2;  
    8.     repeated TopicInfo topicList = 3;  
    9. }  
    10.     
    11. message TopicInfo  {    
    12.   optional string name = 1;  
    13.   optional string type = 2;           
    14.   repeated string entities = 3;    
    15.   repeated string tags = 4;   
    16. }   

    (2)使用例如以下命令编译proto文件。生成相应Java代码


    注:编译成功无消息输出。会产生文件。

    ./ 与 msg.proto中间有空格

    (3)序列化

    1. private SocialRecommend.RecommendInfo transRecommendInfoToPB(RecommendBean recommendInfo) {  
    2.     SocialRecommend.RecommendInfo.Builder builder =   
    3.         SocialRecommend.RecommendInfo.newBuilder();  
    4.     builder.setHid(recommendInfo.hid);  
    5.     builder.setTags(recommendInfo.tags);  
    6.     for(int i = 0; i< recommendInfo.topicList.size(); i++){  
    7.         TopicInfo topicInfo = recommendInfo.topicList.get(i);  
    8.         SocialRecommend.TopicInfo kvTopic = trasnTopicInfoToPB(topicInfo);  
    9.         builder.addTopicList(kvTopic);  
    10.     }  
    11.     return builder.build();  
    12. }  
    1. byte[] pbByteArray = pb.toByteArray();  


     

    (4)反序列化

    1. SocialRecommend.RecommendInfo msg = SocialRecommend.RecommendInfo.parseFrom(pbByteArray);    
    2.             System.out.println(msg);  

    參考http://blog.csdn.net/program_think/article/details/4229773

           http://blog.csdn.net/erli11/article/details/27213239

  • 相关阅读:
    男人只说三分话、留的七分打天下。
    sqlmap实例拿站
    sqlmap使用笔记
    rpm安装删除简介
    Zookeeper技术介绍
    linux下各文件夹的结构说明及用途介绍:
    每个系统管理员都要知道的 30 个 Linux 系统监控工具
    常用命令
    安装gitlab管理自己的代码
    速成Git
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7020073.html
Copyright © 2020-2023  润新知