例子描述是这样的:我们将用户信息(学号,姓名,性别,年龄)由客户端发送到服务端。
实现这个例子,我们大致要做以下几部分事情:
(1)书写.thrift文件
(2)生成cpp文件
(3)编写客户端
(4)编译cpp文件并执行
(1)书写.thrift文件
学生信息是有结构的,所以我们使用thrift的struct即可,为了达到通信的目的,我们必须使用service。
所以最后书写成的demo.thrift文件内容如下:
struct Student1{
1:i32 id, //注意这里是逗号,而不是分号
2:string name,
3:string blurb
} //这里没有分号
service Serv{
void store(1: Student1 user), //注意这里是逗号,而不是分号
Student1 getUser(1: i32 uid)
}
(2)生成cpp文件
生成cpp文件很简单,只需要一个thrift命令即可:
thrift -r --gen cpp demo.thrift
--gen 后指定生成的语言,生成的cpp存储在目录gen-cpp下
命令执行后,将会在./gen-cpp/目录下生成如下文件:
Serv.cpp
Serv.h
Serv_server.skeleton.cpp
demo_constants.cpp
demo_constants.h
demo_types.cpp
demo_types.h
注意文件的大小写:
Serv开头的文件是由service生成的,这个关键字很重要,下面还会见到以它开头的类。
demo是根据demo.thrift文件的名生成的。
这些文件可以进行编译,生成最初的服务端。
注意:在以上文件中,只有Serv_server.skeleton.cpp是跟业务相关的,是可以修改的,其余文件都是框架相关的。
(3)编写客户端
使用thrift命令后,我们并没有得到我们想要的客户端client源代码,因此客户端程序要由我们自己编写实现。然而很幸运,我们可以使用下面的代码段来编写我们client程序:
[c]
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>
#include "Serv.h"
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace boost;
int main(int argc, char** argv) {
shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
ServClient client(protocol);
try {
transport->open();
Student1 user;
user.id = 1;
user.name = "liqb";
user.blurb = "aaaaaa";
client.store(user);
Student1 user2;
client.getUser(user2, 1);
printf("user.id = %d user.name = %s user.blurb = %s\n", user2.id, user2.name.c_str(), user2.blurb.c_str());
transport->close();
} catch (TException &tx) {
printf("ERROR: %s\n", tx.what());
}
}
[/c]
保存成文件client.cpp
(4)编写服务端,文件(Serv_server.skeleton.cpp)只是一个框架,用户可以根据需要扩展该文件,先修改如下:
[c]</pre>
// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.
#include "Serv.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <map>
using namespace std;
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
class ServHandler : virtual public ServIf {
public:
ServHandler() {
// Your initialization goes here
}
void store(const Student1& user) {
// Your implementation goes here
log[user.id] = user; //实际的保存操作
printf("store\n");
}
void getUser(Student1& _return, const int32_t uid) {
// Your implementation goes here
_return = log[uid]; //实际获取操作,注意:在实际生产中,这里还需要异常处理
printf("getUser\n");
}
//增加成员变量,用户保存用户数据,为了简单起见,这里只将数据保存在内存,当然可以可以保存在数据库、文件等等,主要注意,如果保存在其他介质的话
//在初始化的时候记得加载进内存或者打开访问句柄
protected:
map<int32_t, Student1> log;
};
int main(int argc, char **argv) {
int port = 9090;
shared_ptr<ServHandler> handler(new ServHandler());
shared_ptr<TProcessor> processor(new ServProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
<pre>[/c]
(5)编译cpp文件并执行,注意客户端必须运行在另外一个终端里。
编译服务端:g++ -g -DHAVE_NETINET_IN_H -I. -I/usr/local/include/thrift -L/usr/local/lib Serv.cpp demo_types.cpp demo_constants.cpp Serv_server.skeleton.cpp -o server -lthrift
编译客户端:g++ -g -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -L/usr/local/lib/ Serv.cpp demo_types.cpp demo_constants.cpp client.cpp -o client -lpthread -lthrift -lrt
运行服务端:./server
运行客户端:./client
最后编译,运行服务端,启动客户端后,服务端收到消息,显示结果为:
user.id = 1 user.name = liqb user.blurb = aaaaaa
至此,客户端已能向服务端发送数据了。
Linux下复制粘贴文件:
在命令行里,输入sudo nautilus搜索
之后输入你的用户的密码,会弹出一个目录窗口来,可以复制到这里来的,在这里也可以删掉root的文件。
清空回收站:
cd ~/.local/share/Trash/files
rm -rf *