Thrift c++ server / java client配置

在安装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下的客户端进行访问,发现真的成功了~好激动,撒花~✿✿ヽ(°▽°)ノ✿

猜你喜欢

转载自blog.csdn.net/j1231230/article/details/77899160