C++和Ruby使用protobuf做Socket通信 博客分类: C++ RubyCC++C#Socket
程序员文章站
2024-02-22 17:40:34
...
1, people.proto
2, 生成stub类
3, C++服务器端server.cc
4, C++客户端client.cc
5, Ruby客户端client.rb
6, 使用g++编译
7, 运行
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"