在安装thrift前需要安装libevent,用于生成对应的lib链接。
server端
Linux配置
1.下载
从官网http://thrift.apache.org/上下载thrift-0.8.0版本,之前使用的是0.9.3版本,编译时会报错,因而改成了0.8.0版本。
2.解压thrift压缩文件
tar zxvf thrift-0.8.0.tar.gz
3.安装
进入到thrift-0.8.0目录
cd thrift-0.8.0
执行
./configure --prefix=/usr/local/ --with-boost=/usr/local --without-php
make
make install
安装时遇到如下错误
./configure --prefix=/usr/local/
thift configure: error: "Error: libcrypto required."
这个问题百度了下是缺少某些软件导致的,但是因为虚拟机配置问题一直上不了网,就只能依靠网上的建议手动安装某些软件来解决这个问题,然而安装了很多东西还是不行,挣扎许久还是先去解决上网问题了·······
解决虚拟机不能上网问题:
http://jingyan.baidu.com/article/6c67b1d68facbb2786bb1e7b.html
可以上网后,解决Error: libcrypto required.问题:
安装 openssl openssl-devel (centOS)
yum -y install openssl openssl-devel
./configure --prefix=/usr/local/
运行后发现yum命令报错:
This system is not registered with RHN
Redhat之所以会出现这个错误是因为没有注册RHN,只需要更新一下yum的源就可以了。
解决:
进入yum的配置目录
cd /etc/yum.repos.d/
下载CentOS- Base.repo文件
wget http://docs.linuxtone.org/soft/lemp/CentOS-Base.repo
将原有的rhel-debuginfo.repo备份一下
cp rhel-debuginfo.repo rhel-debuginfo2.repo
将CentOS- Base.repo重命名成rhel-debuginfo.repo
mv CentOS-Base.repo rhel-debuginfo.repo
安装成功
yum install build-essential
此时再次执行
./configure --prefix=/usr/local/ --with-boost=/usr/local --without-php
make
make install
在终端输入 thrift –version 终于安装成功
Thrift安装总结:之前尝试在windows下配置c++作为服务器端,java作为客户端封装thrift,但是thrift编译后总是一运行就各种出错,多次尝试失败后只好换到了linux下进行配置和安装=_=
4.定义thrift文件
user.thrift
struct User{
1: string uid,
2: string uname,
3: bool usex,
4: i16 uage,
}
service UserService{
void add(1: User u),
User get(1: string uid),
}
5.通过thrift的shell工具命令生成c++,java代码框架
Shell代码
thrift -r --gen cpp user.thrift
thrift -r --gen java user.thrift
通过执行以上命令:会生成子目录gen-cpp,gen-java。
6.通过执行如下命令,生成C/C++服务端代码
Shell代码
cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp
7.修改服务端的代码,如下所示
#include "UserService.h"
#include <config.h>
#include <protocol/TCompactProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
#include <concurrency/ThreadManager.h>
#include <concurrency/PosixThreadFactory.h>
#include <server/TThreadPoolServer.h>
#include <server/TThreadedServer.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace ::apache::thrift::concurrency;
using boost::shared_ptr;
class UserServiceHandler : virtual public UserServiceIf {
public:
UserServiceHandler() {
}
void add(const User& u) {
printf("uid=%s uname=%s usex=%d uage=%d\n", u.uid.c_str(), u.uname.c_str(), u.usex, u.uage);
if(u.uage<5)
printf("too young");
}
void get(User& _return, const std::string& uid) {
_return.uid = uid;
_return.uname = "喵";
_return.usex = "妹子";
_return.uage = 7;
printf("uid=%s uname=%s usex=%d uage=%d\n", _return.uid.c_str(), _return.uname.c_str(), _return.usex, _return.uage);
}
};
int main(int argc, char **argv) {
shared_ptr<UserServiceHandler> handler(new UserServiceHandler());
shared_ptr<TProcessor> processor(new UserServiceProcessor(handler));
shared_ptr<TProtocolFactory> protocolFactory(new TCompactProtocolFactory());
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));
shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(10);
shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
printf("start user server...\n");
TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);
server.serve();
return 0;
}
这里使用的是TCompactProtocol,则需要#include<config.h>
,还有就是Blocking的多线程服务器。
8.运行如下命令
g++ -g -o UserServer -I /usr/local/include/thrift -I /usr/include/boost/ -I ./gen-cpp -L /usr/local/lib -lthrift UserServer.cpp ./gen-cpp/user_types.cpp ./gen-cpp/user_constants.cpp ./gen-cpp/UserService.cpp
刚开始运行报错,满满一页错误简直丧心病狂,各种找不到文件,因为是按照别人的教程配置的,很多安装细节可能不一样,最后只好根据需要把src文件重命名为thrift放到/usr/local/include/下,并把boost放到/usr/include/下,以及把找不到的config.h放到需要的目录下,再次运行发现错误少了不少,果然是缺少文件的原因。
但是还有报错信息显示thrift自带的包有问题,查找报错的位置,发现是没有加this->引发的错误,加上之后服务器端终于可以运行了,激动哭/(ㄒoㄒ)/~~
client端
Linux下客户端配置:
运行java程序需要有jdk,发现虚拟机上未安装,于是使用yum安装,一切顺利,但是奇怪的是环境变量配置好后,javac命令居然找不到,到对应的路径下发现居然真的没有这个命令·········重新卸载安装多次未果,只好用windows搜索需要的压缩包手动导入了,以下为java安装过程:
1.先卸载服务器自带的jdk软件包
rpm -qa | grep jdk
yum -y remove 显示的java名称
2.从windows下载 jdk-7u67-linux-x64.tar.gz
偷个懒,直接解压用filezilla导入Linux下
3.移动到相应位置
mv jdk-7u67-linux-x64 /usr/lib/jvm/java7
4.添加jdk7.0到系统环境变量
cp /etc/profile /etc/profile.bak
vi /etc/profile
5.编辑添加下面的内容
export JAVA_HOME=/usr/lib/jvm/java7
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
6.保存后在命令行输入如下语句使配置立即生效
source /etc/profile
7.输入如下语句判断是否成功
java -version
客户端java代码:
public static void main(String[] args) {
try {
TTransport transport;
String ip="x.x.x.x";
transport = new TSocket(ip, 9090);
TProtocol protocol = new TBinaryProtocol(transport);
UserService.Client client = new UserService.Client(protocol);
transport.open();
User u = new User();
u.uid = "001";
u.uname="22";
u.usex = "妹子";
u.uage = 3;
client.add(u);
System.out.println("添加用户成功了哟!");
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException x) {
x.printStackTrace();
}
}
安装成功后我就直接把java程序简单粗暴的复制到linux下准备执行了,直接用javac执行的main函数,发现居然找不到jar包里面的类,同时还各种报错,后来才知道正确的打开方式是要打成jar包再执行,简直傻到哭o(╥﹏╥)o。
将jar包导入linux下并执行jar包,当然前提是服务器已经开启。
java -jar client.jar
注:服务器端运行后处于监听状态,此时需要再开一个session开启客户端,之前把服务器停掉又开客户端发现出不来结果还很奇怪=_=,最后可以成功的开始通信了。
客户端:
服务器端:
补充:
Windows下的客户端终于可以用了,原来一直觉得是windows这边的防火墙的问题,各种配置未果,后来突然想到可能是linux下的防火墙,试了一下,果然是!!终于解决了,心情都舒畅了起来~
以下是解决方法:
1.先查看linux下的防火墙配置
iptables -L -n
发现貌似windows能访问的服务都包含在了里面,于是猜测可能需要把服务器这边的端口打开。
2.打开防火墙配置文件
vi /etc/sysconfig/iptables
3.添加如下一行后并保存
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:9091
4.关闭后重新打开防火墙
/etc/rc.d/init.d/iptables stop
/etc/rc.d/init.d/iptables start
再次使用windows下的客户端进行访问,发现真的成功了~好激动,撒花~✿✿ヽ(°▽°)ノ✿