Thrift框架使用C++的一个demo
Thrift编译器会根据选择的目标语言为server产生服务接口代码,为client产生stubs,参数可以是基本类型和结构体。
代码框架用的Thrift,为了了解结构,学习写了一个thrift的Demo。虽然看起来很简单,确实废了不少功夫。下面列下我的步骤和我遇到的问题。
大家也可以参考这个博客:http://blog.csdn.net/hbuxiaoshe/article/details/6558391/
我这边多出来的只有自己遇到的问题总结。
例子描述:我们将学生信息(学号,姓名,性别,年龄)由客户端发送到服务端。
一 编写thrift文件
学生信息使用thrift的struct即可,为了达到通信目的,我们需要写一个service。注意改出service的名字为Serv,方法名字为put。
所以最后写成的student.thrift文件内容如下:
struct Student{
: i32 sno,
: string sname,
: bool ssex,
: i16 sage,
}
service Serv{
void put(: Student s),
}
二 生成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文件夹中的。
g++ -g -Ithrift -L Serv.cpp student_types.cpp student_constants.cpp Serv_server.skeleton.cpp -o server -lthrift
Serv.cpp
Serv.h
Serv_server.skeleton.cpp #简单的server端代码,可以修改,一般都参照它来写serve程序
student_constants.cpp
student_constants.h
student_types.cpp
student_types.h
三 编写客户端client.cpp
thrift最大的好处就是可用c++的服务端,java的客户端;java的服务端,python的客户端等。
中间"//我们的代码卸载这里"后续可以添加代码进去进行测试。
注意此处,原本的include的.h文件路径为下路径,我在运行时报错了,所以换成了全路径。
#include "Serv.h" // 替换成你的.h
#include <transport/TSocket.h>
#include <transport/TBufferTransports.h>
#include <protocol/TBinaryProtocol.h>
#include </home/xiaodan/MyThriftTest/student/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>
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport; using boost::shared_ptr; int main(int argc, char **argv) {
boost::shared_ptr<TSocket> socket(new TSocket("localhost", )); //注意此处的ip和端口
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open(); // 我们的代码写在这里 transport->close();
return ;
}
四 编译
我在这里踩了好几个坑,哭的都没泪了。贴一下我成功的命令。
cd 进入gen-cpp编译server端:g++ -g -Ithrift -L Serv.cpp student_types.cpp student_constants.cpp Serv_server.skeleton.cpp -o server -lthrift
client.cpp我放在了gen-cpp的外面,所以编译client端:
g++ -g -Ithrift -L -lm -pthread -lz -lrt -lssl gen-cpp/Serv.cpp gen-cpp/student_types.cpp gen-cpp/student_constants.cpp client.cpp -o client -lthrift
然后就可以在对应目录下分别看到两个可执行文件
-rwxrwxr-x 1 xiaodan xiaodan 599962 Apr 13 13:59 client
-rwxrwxr-x 1 xiaodan xiaodan 663617 Apr 13 13:57 server
分别启动,执行命令.
./server //可以用ps -ef|grep server查看到启动进程号
./client
五 发送消息进行通信验证
我们把客户端client.cpp当做发送端,编写程序向服务端发送消息
在client.cpp中添加以下代码
transport->open();
//********添加部分***********
Student s;
s.sno = ;
s.sname = "xiaoshe";
s.ssex = ;
s.sage = ;
ServClient client(protocol);
client.put(s);
//********添加部分***********
transport->close();
在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); //********次行为添加代码********
}
再次编译运行
1 启动./server
2 再另外窗口执行./client
3 查看server窗口,即可看到打印信息如下:
put
sno= sname=xiaoshe ssex= sage=
七 问题与总结
1 编译client.cpp提示"client.cpp:2:31: fatal error:transport/TSocket.h:No such file or directory"
在当前路径下执行
find / -name 'TSocket'
发现该文件路径为/usr/local/include/thrift/transport/TSocket.h,于是更新client.cpp的include头文件的路径地址
2 编译client.cpp提示"找不到Serv.h"
同1,更改Serv.h路径为全路径即可
3 使用命令“g++ -g -Ithrift -L -lthrift -lm -pthread -lz -lrt -lssl gen-cpp/Serv.cpp gen-cpp/student_types.cpp gen-cpp/student_constants.cpp client.cpp -o client”编译client.cpp,日志报错: undefined reference to `apache::thrift::TApplicationException::write(apache::thrift::protocol::TProtocol*) const'等等
解决:将编译命令中的ithrift放到最后即可
好像是ithrift执行需要某些加载文件,放在前面的时候,它还没加载会找不到。具体不记得了,在别人的博客里看到过原因,关了就没再找到。感谢博客作者大神。
4 还有个问题,我没解决。编译完成执行过后,更新了Serv_server_skeletion.cpp和client.cpp,再次编译时发生了错误,如下,求问怎么回事?已经kill掉原server进程了。
/tmp/cckgAbGo.o: In function `ServProcessor::ServProcessor(boost::shared_ptr<ServIf>)':
/home/xiaodan/MyThriftTest/student/gen-cpp/Serv.h:: undefined reference to `vtable for ServProcessor'
/home/xiaodan/MyThriftTest/student/gen-cpp/Serv.h:: undefined reference to `ServProcessor::process_put(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
collect2: error: ld returned exit status
5 server的启动也可以使用如下方式
Makefile文件:
BOOST_DIR = /usr/include/boost/
THRIFT_DIR = /usr/local/include/thrift
LIB_DIR = /usr/local/lib
GEN_SRC = ./gen-cpp/user_types.cpp ./gen-cpp/user_constants.cpp ./gen-cpp/UserService.cpp
default: server
server: UserServer.cpp
g++ -g -o UserServer -I${THRIFT_DIR} -I${BOOST_DIR} -I./gen-cpp -L${LIB_DIR} -lthrift UserServer.cpp ${GEN_SRC}
在路径下执行make命令,即可看到日志文件log
Thrift框架使用C++的一个demo的更多相关文章
- gin框架初识(先跑一个简单demo) ①
Gin 是一个 go 写的 web 框架,具有高性能的优点.官方地址:https://github.com/gin-gonic/gin 先跑一个demo(先安装gin框架,具体见官方地址): 1.vs ...
- thrift框架总结,可伸缩的跨语言服务开发框架
thrift框架总结,可伸缩的跨语言服务开发框架 前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等.其 ...
- Thrift笔记(三)--Thrift框架通信源码分析
Thrift 客户端调用RPC的Demo public static void main(String[] args) throws Exception { TTransport transport ...
- angular开发者吐槽react+redux的复杂:“一个demo证明你的开发效率低下”
曾经看到一篇文章,写的是jquery开发者吐槽angular的复杂.作为一个angular开发者,我来吐槽一下react+redux的复杂. 例子 为了让大家看得舒服,我用最简单的一个demo来展示r ...
- springMvc的第一个demo
1.下载jar包 http://repo.spring.io/libs-release-local/org/springframework/spring/4.2.3.RELEASE/ 2.下载源码 j ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)
在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你全然了解它)
在android的应用层中,涉及到非常多应用框架.比如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架.通知机制,ActionBar框架等等. ...
- 定时任务框架Quartz-(一)Quartz入门与Demo搭建
注:本文来源于:是Guava不是瓜娃 <定时任务框架Quartz-(一)Quartz入门与Demo搭建> 一.什么是Quartz 什么是Quartz? Quartz是OpenSympho ...
- .NET Core微服务之路:让我们对上一个Demo通讯进行修改,完成RPC通讯
最近一段时间有些事情耽搁了更新,抱歉各位了. 上一篇我们简单的介绍了DotNetty通信框架,并简单的介绍了基于DotNetty实现了回路(Echo)通信过程. 我们来回忆一下上一个项目的整个流程: ...
随机推荐
- mac下安装mysql 连接时候报错 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
http://segmentfault.com/q/1010000000094608 同样的问题,先在网上搜了下其他人解决这个问题的方法,是去修改mysql.cnf文件添加mysql.sock文件路径 ...
- nslookup工具的使用方法
配置好DNS服务器,添加了相应的记录之后,只要IP地址保持不变,一般情况下我们就不再需要去维护DNS的数据文件了.不过在确认域名解释正常之前我们最好是测试一下所有的配置是否正常.许多人会简单地使用pi ...
- unigui判断浏览器内核、操作系统以及是否移动终端函数
function GetDeviceType(var OsName, BrowserName: string; var IsMobileDevice: Boolean): string; var I: ...
- NSMutableArray 初始化与添加删除程序
Person *person1=[[Person alloc]initWithName:@"Kenshin"]; Person *person2=[[P ...
- WPF中Timer与DispatcherTimer类的区别
前几天在WPF中写了一个轨迹回放的功能,我想稍微做过类似项目的,都晓得采用一个时间控件或者时间对象作为调度器,我在这么做的时候,出现了问题,于是将程序中的Timer换成了DispatchTimer,然 ...
- tlProPlayer for windows
tlProPlayer tlProPlayer简介 tlProPlayer是一款定位高性能产品,支持透传,原生输出,并支持硬解码(硬件加速)的多媒体产品,兼容tlplayer所有特性.支持视频加密播放 ...
- vi编辑器基本用法介绍
vi是Linux系统中编写文件的工具 如果vi出现乱码情况,需要升级vi,命令如下: sudo apt-get install vim //升级vi vi的启动方式有两种,直接使用vi命令和在vi命 ...
- poj 2029 Get Many Persimmon Trees (dp)
题目链接 又是一道完全自己想出来的dp题. 题意:一个w*h的图中,有n个点,给一个s*t的圈,求这个圈能 圈的最多的点 分析:d[i][j]代表i行j列 到第一行第一列的这个方框内有多少个点, 然后 ...
- POJ 2112 - Optimal Milking
原题地址:http://poj.org/problem?id=2112 题目大意:有K个挤奶机(标号为1 ~ K)和C头奶牛(编号为K + 1 ~ K + C),以邻接矩阵的方式给出它们两两之间的距离 ...
- onkeypress与onkeydown及 oncopy和onpaste 事件区别详细说明
onkeypress与onkeydown 具体区别: 1. 一个放开一个没有放开,onkeydown 先于 onkeypress 发生. 2.onkeypress 无法系统按钮. 2.onkeydow ...