protobuf c++例子
1, people.proto
- package demo;
- message People {
- required string name = 1;
- required int32 id = 2;
- required string email = 3;
- }
2, 生成stub类
- protoc --cpp_out=. people.proto
- rprotoc people.proto
3, C++服务器端server.cc
- #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
- #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
- 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++编译
- $ g++ server.cc people.pb.cc -o s -lprotobuf
- $ g++ client.cc people.pb.cc -o c -lprotobuf
7, 运行
- #启动server
- ./s
- You got a message from 127.0.0.1
- Client Message: GET PEOPLE
- You got a message from 127.0.0.1
- Client Message: GET PEOPLE
- #运行c++的client
- ./c "GET PEOPLE"
- People:
- Name: Hideto
- ID: 123
- Email: hideto.bj@gmail.com
- #运行Ruby的client
- ruby client.rb
- name: "Hideto"
- id: 123
- email: "hideto.bj@gmail.com"