目录
1、Thrift基础
1.1 数据类型
基本类型:
- bool:布尔值,true 或 false,对应 C++ 的 bool
- byte:8 位有符号整数,对应 C++ 的 byte
- i16:16 位有符号整数,对应 C++ 的 short
- i32:32 位有符号整数,对应 C++ 的 int
- i64:64 位有符号整数,对应 C++ 的 long
- double:64 位浮点数,对应 C++ 的 double
- string:utf-8编码的字符串,对应 C++ 的 string
结构体类型:
- struct:定义公共的对象,类似于 C 语言中的结构体定义
容器类型:
- list:对应 C++ 的 list
- set:对应 C++ 的 set
- map:对应 C++ 的map
异常类型:
- exception:对应 C++ 的 Exception
服务类型:
- service:对应服务的类
1.2 通讯支持
支持的数据传输协议(传输格式)
- TBinaryProtocol : 二进制格式.
- TCompactProtocol : 压缩格式
- TJSONProtocol : JSON格式
- TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析
- tips: 客户端和服务端的协议要一致
支持的数据传输方式
- TSocket -阻塞式socker
- TFramedTransport–以frame为单位进行传输,非阻塞式服务中使用。
- TFileTransport – 以文件形式进行传输。
- TMemoryTransport –将内存用于I/O. java实现时使用了简单的ByteArrayOutputStream。
- TZlibTransport – 使用zlib进行压缩, 与其他传输方式联合使用。当前无java实现。
支持的服务模型
- TSimpleServer – 简单的单线程服务模型,常用于测试教学使用
- TThreadPoolServer – 多线程服务模型,使用标准的阻塞式IO。
- TNonblockingServer – 多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式)
2、Linux环境安装Thrift
(1)安装依赖项:
sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev
(2)将thrift安装包下载下来,并解压安装
tar -zxvf thrift-0.13.0.tar.gz
cd thrift-0.13.0/
./configure
sudo make
sudo make install
(3)测试安装是否成功
thrift -version
3、编写c++测试用例
例子描述:我们将学生信息(学号,姓名,性别,年龄)由客户端发送到服务端。
3.1 编写thrift文件
学生信息使用thrift的struct即可,为了达到通信目的,我们需要写一个service。注意改出service的名字为Serv,方法名字为put。
student.thrift文件内容如下:
struct Student{
1: i32 sno,
2: string sname,
3: bool ssex,
4: i16 sage,
}
service Serv{
void put(1: Student s),
}
3.2 生成cpp文件
thrift可以简易生成不同语言的代码,c++ python java等,此处我们只用--gen cpp第一个命令即可
thrift -r --gen cpp student.thrift
#thrift -r --gen java student.thrift //生成java代码
#thrift -r --gen py student.thrift //生成python代码
如下生成7个文件:Serv开头的文件是由service的名字生成的,查看Serv_server.skeleton.cpp可以看到put方法。这些文件可以编译,生成最初的客户端,编译命令如下:
cd到gen-cpp所在的文件夹,执行如下编译命令,注意生成的server可执行文件是在gen-cpp文件夹中的。
Serv.cpp
Serv.h
Serv_server.skeleton.cpp #简单的server端代码,可以修改,一般都参照它来写serve程序
student_constants.cpp
student_constants.h
student_types.cpp
student_types.h
3.3 编写客户端client.cpp
#include "./gen-cpp/Serv.h"
#include </usr/local/include/thrift/transport/TSocket.h>
#include </usr/local/include/thrift/transport/TBufferTransports.h>
#include </usr/local/include/thrift/protocol/TBinaryProtocol.h>
#include <iostream>
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
//using boost::shared_ptr;
int main(int argc, char **argv) {
std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));
std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
//*****************添加部分******************
Student s;
s.sno = 123;
s.sname = "xiaoshe";
s.ssex = 1;
s.sage = 30;
ServClient client(protocol);
std::cout<<"client send a data"<<std::endl;;
client.put(s);
//*****************添加部分******************
transport->close();
return 0;
}
编译:g++ -g -o client -Ithrift client.cpp gen-cpp/Serv.cpp gen-cpp/student_types.cpp gen-cpp/student_constants.cpp -lthrift
3.4 服务端代码
在Serv_server.skeleton.cpp中添加打印信息如下:
void put(const Student& s) {
// Your implementation goes here
printf("put\n");
printf("sno=%d sname=%s ssex=%d sage=%d/n", s.sno, s.sname.c_str(), s.ssex, s.sage); //********次行为添加代码********
}
编译:g++ -g -o server -Ithrift Serv.cpp student_types.cpp student_constants.cpp Serv_server.skeleton.cpp -lthrift
3.5 编译运行
(1)启动服务端:./server
(2)启动客户端:./client
客户端结果:
服务端结果:
注:更多测试用例可参照 thrift-0.13.0/test/ 目录下的demo。
参考: