Protobuf
Table of Contents
Homepage
- Protocol Buffers - Google's data interchange format https://developers.google.com/protocol-buffers/
- https://github.com/google/protobuf
Install
- On Ubuntu, install need tools
$ sudo apt-get install autoconf automake libtool curl
- Install
$ ./autogen.sh $ ./configure $ make $ make check $ sudo make install $ sudo ldconfig # refresh shared library cache.
Compiling dependent packages
pkg-config --cflags protobuf # print compiler flags pkg-config --libs protobuf # print linker flags pkg-config --cflags --libs protobuf # print both c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
Third-Party Add-ons for Protocol Buffers
Protobuf examples
A example of transmitting a personal info from a server to a client.
Define message formats in a .proto file.
person.proto
syntax = "proto3"; package example; message Person { string name = 1; int32 id = 2; // Unique ID number for this person. string email = 3; }
A server to send the personal info
#include <string.h> // for bzero #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string> #include <cstdlib> #include <iostream> #include <google/protobuf/message_lite.h> #include "person.pb.h" using namespace std; #define SERVER_PORT 9999 #define LISTEN_COUNT 5 void error(const char *msg) { perror(msg); exit(1); } int main() { struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htons(INADDR_ANY); server_addr.sin_port = htons(SERVER_PORT); int server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket < 0) { error("Open socket failed"); } int enable = 1; if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) { error("setsockopt(SO_REUSEADDR) failed"); } if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { error("Server bind port failed"); } listen(server_socket, LISTEN_COUNT); while (true) { struct sockaddr_in client_addr; int new_socket = accept(server_socket, 0, 0); if (new_socket < 0) { error("Server accept failed"); } example::Person person; person.set_name("example"); person.set_id(1); person.set_email("example@gmail.com"); int len = person.ByteSize(); char *buffer = new char[len]; person.SerializeToArray(buffer, len); if (write(new_socket, buffer, len) < 0) { delete buffer; cout << "Send Failed" << endl; break; } close(new_socket); delete buffer; } close(server_socket); return 0; }
A client to receive the personal info
#include <string.h> // for bzero #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <string> #include <cstdlib> #include <iostream> #include <google/protobuf/message_lite.h> #include "person.pb.h" using namespace std; void error(const char *msg) { perror(msg); exit(1); } #define SERVER_PORT 9999 int main() { int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket < 0) { error("Open socket failed"); } struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(SERVER_PORT); if (connect(client_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) == 0) { char buf[1024]; int count = read(client_socket, buf, 1024); example::Person person; person.ParseFromArray(buf, count); cout << "name:" << person.name() << endl; cout << "id:" << person.id() << endl; cout << "email:" << person.email() << endl; } }
Compiling
protoc --cpp_out=. person.proto c++ server.cc person.pb.cc -o server `pkg-config --cflags --libs protobuf` c++ client.cc person.pb.cc -o client `pkg-config --cflags --libs protobuf`
Run
$ ./server $ ./client name:example id:1 email:example@gmail.com