Cmake + protobuf-c + python自定义协议通信
Cmake是一套跨平台的工程构建工具
?
sudo apt-get install cmake
?
一个Cmake的例子
生成一个demo工程,包括一个hello.cpp文件(在demo工程下)
?
#include <stdio.h>int main(int argc, char **argv){ printf("Hello world!\n"); return 0;}
?
Cmake构建该工程
Cmake需要CMakeLists.txt文件来配置,在demo目录下创建CMakeLists.txt文件
PROJECT (Test)SET(SRC_LIST hello.cpp)ADD_EXECUTABLE(test ${SRC_LIST})
?
?
构建项目
cmake .
便会生成相应的Makefile文件
?
Protobuf
安装protobuf-c
?
需要先安装google protobuf
?
http://code.google.com/p/protobuf/downloads/list
?
./configure
?
make
make check
make install
?
下载
http://code.google.com/p/protobuf-c/downloads/list
./configure --prefix=$HOME/install
make
make install
?
A typical reason for this behaviour is a stale ld.so.cache; try to run ldconfig to update it after making sure that /usr/local/lib is listed in /etc/ld.so.conf.
make不过时可能需要执行 ldconfig 命令
To install into /usr like a normal package would, use --prefix=/usr
?
protobuf-c Simple complete example
protobuf-c works by taking a.proto file, and generating both .h and .c files for use in C programs.
?
amessage.proto
?
message AMessage { required int32 a=1; optional int32 b=2; }?
?
Generate .h and .c files from the command-line in your current working directory:
protoc-c --c_out=. amessage.proto?
?
Serialize/pack Deserialize/upack the AMessage as follows:
amessage_demo.c
?
#include <stdio.h>#include <stdlib.h>#include "amessage.pb-c.h"int main (int argc, const char * argv[]) { AMessage msg = AMESSAGE__INIT; // AMessage AMessage *rmsg; void *buf; // Buffer to store serialized data unsigned len; // Length of serialized data if (argc != 2 && argc != 3) { // Allow one or two integers fprintf(stderr,"usage: amessage a [b]\n"); return 1; } msg.a = atoi(argv[1]); // Put an int in msg if (argc == 3) { msg.has_b = 1; msg.b = atoi(argv[2]); } // Add another len = amessage__get_packed_size(&msg); // This is calculated packing length buf = malloc(len); // Allocated memory for packed/encode serialized data amessage__pack(&msg,buf); // Put it in buf now fprintf(stderr,"Writing %d serialized bytes\n",len); // See the length of message fwrite(buf,len,1,stdout); // Write to stdout to allow direct command line piping rmsg = amessage__unpack(NULL, len, buf); printf("Received: a=%d", rmsg->a); printf(" b=%d", rmsg->b); printf("\n"); amessage__free_unpacked(rmsg, NULL); free(buf); // Free the allocated serialized buffer return 0;}
?
?编译:
gcc amessage_demo.c amessage.pb-c.c -o amessage_demo -lprotobuf-c
?
效果:
?
./amessage_demo 10 2
Writing: 4 serialized bytes
Received: a=10 b=2
?
安装protobuf-python环境:
?
cd protobuf目录下python目录
?
python setup.py install
?
Protobuf-c RPC service and Protobuf python client
?
首先写一个结构,重点是加上service这样会生成相应的service方法
?
rpc.proto
?
package demo;message SearchRequest { required string keyword = 1;}message SearchResponse { required string result = 1;}service RpcService { rpc Search (SearchRequest) returns (SearchResponse);}?
?
在service中要实现的方法
?
ProtobufCService *protbuf_c_rpc_client_new
?
ProtobufC_RPC_Server *protobuf_c_rpc_server_new
?
python实现protobuf rpc
?
protobuf-socket-rpc
?
python protobuf rpc using tcp/ip sockets
?
http://code.google.com/p/protobuf-socket-rpc/downloads/list
?
在源码中有实例
?
Note: 在.proto文件中加入
?
option py_generic_services = true;
?
ruby实现protobuf rpc
?
gem install ruby_protobuf
?
rpc.proto
?
package demo;message SearchRequest { required string keyword = 1;}message SearchResponse { required string result = 1;}service RpcService { rpc Search (SearchRequest) returns (SearchResponse);}?
?
rproto rpc.proto
?
rpc_service.rb
?
require 'rubygems'require 'protobuf/rpc/server' require 'protobuf/rpc/handler' require 'rpc.pb' class Demo::SearchHandler < Protobuf::Rpc::Handler request Demo::SearchRequest response Demo::SearchResponse def self.process_request(request, response) if request.keyword == 'google' response.result = 'www.google.com' elsif request.keyword == 'freewheel' response.result = 'www.freewheel.tv' else response.result = '' end end end class Demo::RpcService < Protobuf::Rpc::Server def setup_handlers @handlers = { :search => Demo::SearchHandler, } end end?
?
client_search.rb
?
#!/usr/bin/env ruby require 'rubygems' require 'protobuf/rpc/client' require 'rpc.pb'# build request request1 = Demo::SearchRequest.new request1.keyword = 'google' request2 = Demo::SearchRequest.new request2.keyword = 'freewheel' # create blunk response response1 = Demo::SearchResponse.new response2 = Demo::SearchResponse.new # execute rpc Protobuf::Rpc::Client.new('localhost', 9999).call :search, request1, response1 Protobuf::Rpc::Client.new('localhost', 9999).call :search, request2, response2 p response1.result p response2.result?
?
ruby start_rpc_service
?
ruby client_search.rb ?
?
未完成...
?
ps:
?
http://code.google.com/p/protobuf/
?
?