`

转载-protobuf 反射应用例子

 
阅读更多

看了下Google Protobuf的源码,对于反射机制,无论c++实现还是java实现都是采用map查找,这个应很高效率。实际我们在项目中无形中也用 到了这种思路,仅仅没系统化。通过一个类的原型对象做辅助,然后配合map结构,就可很简单的根据符号名字来反射对象。从而实现一种抽象接口的稳定,把变 化隔离到了通讯协议 的数据内。

可参考http://blog.chinaunix.net/uid-52437-id-3142718.html文章。

原型 prototype pattern参考http://blog.chinaunix.net/uid-52437-id-2108601.html 

wiki:  http://en.wikipedia.org/wiki/Prototype_pattern

看一下从网络反射过程:

点击(此处)折叠或打开

  1. inline google::protobuf::Message* createMessage(const std::string& type_name)
  2. {
  3.   google::protobuf::Message* message = NULL;
  4.   const google::protobuf::Descriptor* descriptor =
  5.     google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(type_name);
  6.   if (descriptor)
  7.   {
  8.     const google::protobuf::Message* prototype =
  9.       google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
  10.     if (prototype)
  11.     {
  12.       message = prototype->New();
  13.     }
  14.   }
  15.   return message;
  16. }
  17. //////////////以下是使用
  18. buf[numbytes] = '\0'; //buf为从网络收到的数据
  19. String data = buf;
  20. //"gamesrv.RepLuaMsg"为 类名字
  21. google::protobuf::Message* reply = createMessage("gamesrv.RepLuaMsg");
  22. //gamesrv::RepLuaMsg p2;
  23. reply->ParseFromString(data); //直接反序列化


下面是一个采用反射实现的简单客户端

点击(此处)折叠或打开

  1. // g++ -g `pkg-config --cflags protobuf` luaclient.cpp LuaCmd.pb.cc -o luacli `pkg-config --libs protobuf`
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <strings.h>
  5. #include <stdlib.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <netdb.h>
  10. #include <string>
  11. #include <iostream>
  12. #include "LuaCmd.pb.h"
  13. #include <google/protobuf/descriptor.h>
  14.                           
  15. #include <google/protobuf/dynamic_message.h>
  16. #define HOST "localhost"
  17. #define PORT 8889
  18. #define MAXDATASIZE 100
  19. using namespace std;
  20. inline google::protobuf::Message* createMessage(const std::string& type_name)
  21. {
  22.   google::protobuf::Message* message = NULL;
  23.   const google::protobuf::Descriptor* descriptor =
  24.     google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(type_name);
  25.   if (descriptor)
  26.   {
  27.     const google::protobuf::Message* prototype =
  28.       google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
  29.     if (prototype)
  30.     {
  31.       message = prototype->New();
  32.     }
  33.   }
  34.   return message;
  35. }
  36. int main(int argc, char ** argv)
  37. {
  38.   int fd, numbytes;
  39.   char buf[MAXDATASIZE];
  40.   struct hostent *he;
  41.   struct sockaddr_in server;
  42.   
  43.   
  44.   
  45.   if (argc != 2) {
  46.     printf("Usage: %s \"COMMAND\"\n",argv[0]);
  47.     exit(0);
  48.   } 
  49.   
  50.   he = gethostbyname("10.57.220.70");
  51.   fd = socket(AF_INET, SOCK_STREAM, 0);
  52.   bzero(&server, sizeof(server));
  53.   server.sin_family = AF_INET;
  54.   server.sin_port = htons(PORT);
  55.   server.sin_addr = *((struct in_addr *)he->h_addr);
  56.   int ret = connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr));
  57.   
  58.   //for send 
  59.   string data;
  60.   int cmdid = 1000;
  61.   char szTemp[1024]={'\0'};
  62.   gamesrv::LuaMsg p;
  63.   p.set_account("123");
  64.   p.set_msg("hideto.bj@gmail.com");
  65.   p.SerializeToString(&data);
  66.   
  67.   *(int*)(szTemp+4) = htonl(cmdid);
  68.   int len = 4+4;
  69.   memmove(szTemp+8,data.c_str(),data.length());
  70.   len +=data.length();
  71.   *(int*)(szTemp) = htonl(len);
  72.   ret =send(fd, szTemp, len, 0);
  73.   
  74.   memset(buf,0,sizeof(buf));
  75.   numbytes = recv(fd, buf, 8, 0);
  76.   numbytes = ntohl(*(int*)(buf))-8;
  77.   ret = recv(fd, buf, numbytes, 0);
  78.   
  79.   buf[numbytes] = '\0';
  80.   data = buf;
  81.  
  82.   google::protobuf::Message* reply = createMessage("gamesrv.RepLuaMsg");
  83.    
  84.   reply->ParseFromString(data);
  85.   gamesrv::RepLuaMsg* rep = (gamesrv::RepLuaMsg*)reply;
  86.   cout << "People: " << endl;
  87.   cout << "ID: " << rep->account() << endl;
  88.   cout << "Email: " << rep->msg() << endl;
  89.   string mm = rep->msg();
  90.   close(fd);
  91.   
  92.   
  93.   
  94.   return 0;
  95. }

对应的proto文件LuaCmd.proto

点击(此处)折叠或打开

  1. package gamesrv;
  2. option java_package = "gamesrv.Request.protocol";
  3. option java_outer_classname = "LuaCmdProtos";
  4. message LuaMsg {
  5.     required string account = 1; // Unique ID number for this person.
  6.   optional string msg = 2;
  7. }
  8. message RepLuaMsg {
  9.   required string account = 1; // Unique ID number for this person.
  10.   optional string msg = 2;
  11.   }
分享到:
评论

相关推荐

    activemq-protobuf-1.1-API文档-中文版.zip

    赠送jar包:activemq-protobuf-1.1.jar; 赠送原API文档:activemq-protobuf-1.1-javadoc.jar; 赠送源代码:activemq-protobuf-1.1-sources.jar; 包含翻译后的API文档:activemq-protobuf-1.1-javadoc-API文档-...

    activemq-protobuf-1.1.jar

    activemq-protobuf-1.1.jar;activemq-protobuf-1.1.jar

    grpc-protobuf-1.24.0-API文档-中文版.zip

    赠送jar包:grpc-protobuf-1.24.0.jar; 赠送原API文档:grpc-protobuf-1.24.0-javadoc.jar; 赠送源代码:grpc-protobuf-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-protobuf-1.24.0.pom; 包含翻译后的API...

    grpc-protobuf-1.24.0-API文档-中英对照版.zip

    赠送jar包:grpc-protobuf-1.24.0.jar; 赠送原API文档:grpc-protobuf-1.24.0-javadoc.jar; 赠送源代码:grpc-protobuf-1.24.0-sources.jar; 赠送Maven依赖信息文件:grpc-protobuf-1.24.0.pom; 包含翻译后的API...

    activemq-protobuf-1.1-API文档-中英对照版.zip

    赠送jar包:activemq-protobuf-1.1.jar; 赠送原API文档:activemq-protobuf-1.1-javadoc.jar; 赠送源代码:activemq-protobuf-1.1-sources.jar; 包含翻译后的API文档:activemq-protobuf-1.1-javadoc-API文档-...

    activemq-protobuf-test-1.1.jar

    标签:activemq-protobuf-test-1.1.jar,activemq,protobuf,test,1.1,jar包下载,依赖包

    akka-protobuf_2.11-2.4.20-API文档-中英对照版.zip

    赠送jar包:akka-protobuf_2.11-2.4.20.jar; 赠送原API文档:akka-protobuf_2.11-2.4.20-javadoc.jar; 赠送源代码:akka-protobuf_2.11-2.4.20-sources.jar; 赠送Maven依赖信息文件:akka-protobuf_2.11-2.4.20....

    akka-protobuf_2.11-2.4.20-API文档-中文版.zip

    赠送jar包:akka-protobuf_2.11-2.4.20.jar; 赠送原API文档:akka-protobuf_2.11-2.4.20-javadoc.jar; 赠送源代码:akka-protobuf_2.11-2.4.20-sources.jar; 赠送Maven依赖信息文件:akka-protobuf_2.11-2.4.20....

    js-protobuf-encode-decode-master.zip

    本项目"js-protobuf-encode-decode-master.zip"提供了一个在线工具,专门用于处理JavaScript环境下的Protobuf编码和解码操作。 Protobuf是一种由Google开发的数据序列化协议,它定义了一种二进制数据格式,比JSON...

    activemq-protobuf-pom-1.0-source-release.zip

    标签:activemq-protobuf-pom-1.0-source-release.zip,activemq,protobuf,pom,1.0,source,release.zip包下载,依赖包

    activemq-protobuf-pom-1.1-source-release.tar.gz

    标签:activemq-protobuf-pom-1.1-source-release.tar.gz,activemq,protobuf,pom,1.1,source,release.tar.gz包下载,依赖包

    spring-mvc-tutorial-protobuf

    X-Protobuf-Schema: src/main/proto/tutorial/addressbook.proto &lt; X-Protobuf-Message: tutorial.Person &lt; Content-Type: application/x-protobuf ; charset=UTF-8 &lt; Content-Length:

    google-protobuf.jar

    本文将深入探讨protobuf的核心概念,并重点解析google-protobuf.jar在实际应用中的作用。 protobuf是一种二进制数据表示方式,它的主要优点在于比XML等文本格式更节省存储空间和传输带宽,同时在序列化和反序列化...

    PyPI 官网下载 | typescript-protobuf-0.3.tar.gz

    《PyPI官网下载 | TypeScript-protobuf-0.3.tar.gz:探索TypeScript与protobuf的集成应用》 在软件开发领域,高效的数据交换和序列化是关键环节,而Protocol Buffers(protobuf)作为Google推出的一种数据序列化...

    开源项目-golang-protobuf.zip

    在这个开源项目中,"protobuf-master"目录很可能是包含了项目的主分支或主线代码。通常,这个目录会包含以下组件: 1. **.proto** 文件:这些是protobuf的接口定义文件,其中定义了消息类型、服务以及它们的字段。...

    idea-plugin-protobuf.zip

    idea-plugin-protobuf 是 Intellij IDEA 的插件,用来实现对 Google Protocol Buffes 的支持。

    google-protobuf-java-2.6.1.jar

    google-protobuf-java-2.6.1.jar 使用github下载的源码生成的jar包。

    开源项目-google-protobuf.zip

    开源项目-google-protobuf.zip,Release Protocol Buffers v3.0.0 路 google/protobuf 路 GitHub

Global site tag (gtag.js) - Google Analytics