注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liangxh2008的博客

 
 
 

日志

 
 

在C++和Ruby使用protobuf做Socket通信  

2010-04-14 23:24:03|  分类: AppMarket |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
http://hideto.javaeye.com/blog/445848

1, people.proto
Ruby代码 复制代码
  1. package demo;   
  2.   
  3. message People {   
  4.   required string name = 1;   
  5.   required int32 id = 2;   
  6.   required string email = 3;   
  7. }  
package demo;    message People {    required string name = 1;    required int32 id = 2;    required string email = 3;  }  


2, 生成stub类
Ruby代码 复制代码
  1. protoc --cpp_out=. people.proto   
  2. rprotoc people.proto  
protoc --cpp_out=. people.proto  rprotoc people.proto  


3, C++服务器端server.cc
C++代码 复制代码
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <strings.h>   
  4. #include <unistd.h>   
  5. #include <sys/types.h>   
  6. #include <sys/socket.h>   
  7. #include <netinet/in.h>   
  8. #include <arpa/inet.h>   
  9. #include <string>   
  10. #include <iostream>   
  11. #include "people.pb.h"   
  12.   
  13. #define PORT 8888   
  14. #define MAXDATASIZE 20   
  15. #define BACKLOG 10   
  16.   
  17. using namespace std;   
  18.   
  19. int main()   
  20. {   
  21.   int listenfd, connectfd, numbytes;   
  22.   char buf[MAXDATASIZE];   
  23.   struct sockaddr_in server;   
  24.   struct sockaddr_in client;   
  25.   int sin_size;   
  26.   
  27.   listenfd = socket(AF_INET, SOCK_STREAM, 0);   
  28.   
  29.   int opt = SO_REUSEADDR;   
  30.   setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));   
  31.   
  32.   bzero(&server, sizeof(server));   
  33.   server.sin_family = AF_INET;   
  34.   server.sin_port = htons(PORT);   
  35.   server.sin_addr.s_addr = htonl(INADDR_ANY);   
  36.   
  37.   bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr));   
  38.   
  39.   listen(listenfd,BACKLOG);   
  40.   
  41.   while(1){   
  42.     sin_size = sizeof(struct sockaddr_in);   
  43.   
  44.     connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size);   
  45.   
  46.     numbytes = recv(connectfd, buf, MAXDATASIZE, 0);   
  47.     buf[numbytes] = '\0';   
  48.     string a = buf;   
  49.     cout << "You got a message from " << inet_ntoa(client.sin_addr) << endl;   
  50.     cout << "Client Message: " << a << endl;   
  51.     if(a == "GET PEOPLE") {   
  52.       string data;   
  53.       demo::People p;   
  54.       p.set_name("Hideto");   
  55.       p.set_id(123);   
  56.       p.set_email("hideto.bj@gmail.com");   
  57.       p.SerializeToString(&data);   
  58.       char bts[data.length()];   
  59.       strcpy(bts, data.c_str());   
  60.       send(connectfd, bts, sizeof(bts), 0);   
  61.     } else {   
  62.       send(connectfd, "Fucking client!\n", 16, 0);   
  63.     }   
  64.     close(connectfd);   
  65.   }   
  66.   
  67.   close(listenfd);   
  68.   return 0;   
  69. }  
#include <stdio.h>  #include <stdlib.h>  #include <strings.h>  #include <unistd.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h>  #include <string>  #include <iostream>  #include "people.pb.h"    #define PORT 8888  #define MAXDATASIZE 20  #define BACKLOG 10    using namespace std;    int main()  {    int listenfd, connectfd, numbytes;    char buf[MAXDATASIZE];    struct sockaddr_in server;    struct sockaddr_in client;    int sin_size;      listenfd = socket(AF_INET, SOCK_STREAM, 0);      int opt = SO_REUSEADDR;    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));      bzero(&server, sizeof(server));    server.sin_family = AF_INET;    server.sin_port = htons(PORT);    server.sin_addr.s_addr = htonl(INADDR_ANY);      bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr));      listen(listenfd,BACKLOG);      while(1){      sin_size = sizeof(struct sockaddr_in);        connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size);        numbytes = recv(connectfd, buf, MAXDATASIZE, 0);      buf[numbytes] = '\0';      string a = buf;      cout << "You got a message from " << inet_ntoa(client.sin_addr) << endl;      cout << "Client Message: " << a << endl;      if(a == "GET PEOPLE") {        string data;        demo::People p;        p.set_name("Hideto");        p.set_id(123);        p.set_email("hideto.bj@gmail.com");        p.SerializeToString(&data);        char bts[data.length()];        strcpy(bts, data.c_str());        send(connectfd, bts, sizeof(bts), 0);      } else {        send(connectfd, "Fucking client!\n", 16, 0);      }      close(connectfd);    }      close(listenfd);    return 0;  }  


4, C++客户端client.cc
C++代码 复制代码
  1. #include <stdio.h>   
  2. #include <unistd.h>   
  3. #include <strings.h>   
  4. #include <stdlib.h>   
  5. #include <sys/types.h>   
  6. #include <sys/socket.h>   
  7. #include <netinet/in.h>   
  8. #include <netdb.h>   
  9. #include <string>   
  10. #include <iostream>   
  11. #include "people.pb.h"   
  12.   
  13. #define HOST "localhost"   
  14. #define PORT 8888   
  15. #define MAXDATASIZE 100   
  16.   
  17. using namespace std;   
  18.   
  19. int main(int argc, char ** argv)   
  20. {   
  21.   int fd, numbytes;   
  22.   char buf[MAXDATASIZE];   
  23.   struct hostent *he;   
  24.   struct sockaddr_in server;   
  25.      
  26.   if (argc != 2) {   
  27.     printf("Usage: %s \"COMMAND\"\n",argv[0]);   
  28.     exit(0);   
  29.   }    
  30.      
  31.   he = gethostbyname(HOST);   
  32.   fd = socket(AF_INET, SOCK_STREAM, 0);   
  33.   bzero(&server, sizeof(server));   
  34.   server.sin_family = AF_INET;   
  35.   server.sin_port = htons(PORT);   
  36.   server.sin_addr = *((struct in_addr *)he->h_addr);   
  37.   
  38.   connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr));   
  39.   
  40.   send(fd, argv[1], 20, 0);   
  41.   
  42.   numbytes = recv(fd, buf, MAXDATASIZE, 0);   
  43.   buf[numbytes] = '\0';   
  44.   string data = buf;   
  45.   demo::People p;   
  46.   p.ParseFromString(data);   
  47.   cout << "People: " << endl;   
  48.   cout << "Name: " << p.name() << endl;   
  49.   cout << "ID: " << p.id() << endl;   
  50.   cout << "Email: " << p.email() << endl;   
  51.   
  52.   close(fd);   
  53.   return 0;   
  54. }  
#include <stdio.h>  #include <unistd.h>  #include <strings.h>  #include <stdlib.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <netdb.h>  #include <string>  #include <iostream>  #include "people.pb.h"    #define HOST "localhost"  #define PORT 8888  #define MAXDATASIZE 100    using namespace std;    int main(int argc, char ** argv)  {    int fd, numbytes;    char buf[MAXDATASIZE];    struct hostent *he;    struct sockaddr_in server;        if (argc != 2) {      printf("Usage: %s \"COMMAND\"\n",argv[0]);      exit(0);    }         he = gethostbyname(HOST);    fd = socket(AF_INET, SOCK_STREAM, 0);    bzero(&server, sizeof(server));    server.sin_family = AF_INET;    server.sin_port = htons(PORT);    server.sin_addr = *((struct in_addr *)he->h_addr);      connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr));      send(fd, argv[1], 20, 0);      numbytes = recv(fd, buf, MAXDATASIZE, 0);    buf[numbytes] = '\0';    string data = buf;    demo::People p;    p.ParseFromString(data);    cout << "People: " << endl;    cout << "Name: " << p.name() << endl;    cout << "ID: " << p.id() << endl;    cout << "Email: " << p.email() << endl;      close(fd);    return 0;  }  


5, Ruby客户端client.rb
Ruby代码 复制代码
  1. require 'socket'  
  2. require 'people.pb.rb'  
  3.   
  4. HOST = "localhost"  
  5. PORT = 8888   
  6.   
  7. client = TCPSocket.open(HOST, PORT)   
  8. client.send("GET PEOPLE", 0)   
  9. client.close_write   
  10. s = client.read   
  11. p = Demo::People.new  
  12. p.parse_from_string s   
  13. p p  
require 'socket'  require 'people.pb.rb'    HOST = "localhost"  PORT = 8888    client = TCPSocket.open(HOST, PORT)  client.send("GET PEOPLE", 0)  client.close_write  s = client.read  p = Demo::People.new  p.parse_from_string s  p p  


6, 使用g++编译
C++代码 复制代码
  1. $ g++ server.cc people.pb.cc -o s -lprotobuf   
  2. $ g++ client.cc people.pb.cc -o c -lprotobuf  
$ g++ server.cc people.pb.cc -o s -lprotobuf  $ g++ client.cc people.pb.cc -o c -lprotobuf  


7, 运行
Ruby代码 复制代码
  1. #启动server   
  2. ./s   
  3.   
  4. You got a message from 127.0.0.1   
  5. Client Message: GET PEOPLE   
  6. You got a message from 127.0.0.1   
  7. Client Message: GET PEOPLE   
  8.   
  9. #运行c++的client   
  10. ./c "GET PEOPLE"  
  11.   
  12. People:   
  13. Name: Hideto   
  14. ID: 123   
  15. Email: hideto.bj@gmail.com   
  16.   
  17.   
  18. #运行Ruby的client   
  19. ruby client.rb   
  20.   
  21. name: "Hideto"  
  22. id: 123   
  23. email: "hideto.bj@gmail.com"  
  评论这张
 
阅读(658)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017