Thrift C++サーバとクライアントの開発例--学習ノート2


参考:Thrift C++サーバとクライアント開発例–ノートostringstreamのクリア方法を学習
コード:ThriftLearnCode
以下に、Thrift C++で記述した例を示す.学習の記録:
Thriftバージョン:
# /usr/local/thrift/bin/thrift --version
Thrift version 0.10.0

Thriftコマンド:
/usr/local/thrift/bin/thrift -o ./thrift/ --gen cpp ./thrift/student.thrift

生成されたファイル:
student_constants.cpp
student_constants.h
StudentServ.cpp
StudentServ.h
StudentServ_server.skeleton.cpp
student_types.cpp
student_types.h

Serverエンドコード:server.cpp
//server.cpp
#include "StudentServ.h"
#include 
#include 
#include 
#include 

#include 
#include "inifile.h"

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;

using boost::shared_ptr;
using namespace std;


//        
bool InitConfInfo(const std::string& file, int& port) {
    CIniFile ini;
    std::string str_val;
    if (!ini.Init(file)) {
        printf("ini init file failed: %s
"
, file.c_str()); return false; } // load config ini.Read_Profile_String("server", "port", str_val); if (!str_val.empty()) port = atoi(str_val.c_str()); else port = 8828; return true; } class ServerHandler : virtual public StudentServIf { public: ServerHandler() { // Your initialization goes here } void work_score(sturesult& _return, const student& stu) { ostringstream myout; myout.clear(); stu.printTo(myout); printf("student: %s
"
, myout.str().c_str()); _return.__set_i_uid(stu.i_uid); _return.__set_str_name(stu.str_name); _return.__set_str_sex(stu.str_sex); _return.__set_i_subscore(200); _return.__set_i_subscore(85); _return.__set_str_maxsub("Match"); _return.__set_str_mixsub("English"); myout.str("");// _return.printTo(myout); printf("return info:%s
"
, myout.str().c_str()); printf("ServerHandler work_score
"
); } }; int main(int argc, char **argv) { string conffile = "conf/conf.ini"; int port = 9090; if(!InitConfInfo(conffile, port)){ return -1; } printf("Server Port:%d
"
, port); boost::shared_ptr handler(new ServerHandler()); boost::shared_ptr processor(new StudentServProcessor(handler)); boost::shared_ptr serverTransport(new TServerSocket(port)); boost::shared_ptr transportFactory(new TBufferedTransportFactory()); boost::shared_ptr protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); server.serve(); return 0; }

Clientエンドコード:client.cpp
//client.cpp
#include "StudentServ.h"
#include 
#include 
#include 

#include 
#include "inifile.h"

using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using boost::shared_ptr;

void sendRecv();
bool InitConfInfo(const std::string& file, string& str_ip, int& port);

int main()
{
    sendRecv();
    return 0;
}

void sendRecv()
{
    string conffile = "conf/conf.ini";
    std::string str_ip = "127.0.0.1";
    int port = 9090;
    if(!InitConfInfo(conffile, str_ip, port)){
        return ;
    }
    printf("serverip: %s, port: %d
"
, str_ip.c_str(), port); boost::shared_ptr socket(new TSocket(str_ip.c_str(), port)); boost::shared_ptr transport(new TBufferedTransport(socket)); boost::shared_ptr protocol(new TBinaryProtocol(transport)); socket->setConnTimeout(1000); socket->setRecvTimeout(1000*10000); transport->open(); StudentServClient* pClient = new StudentServClient(protocol); sturesult retinfo; student stu; std::vector vec_subscore; for(int i=0; i<3; ++i){ subjectscore subscore; if(0 == i){ subscore.__set_str_subject("Match"); subscore.__set_i_score(88); }else if(1 == i){ subscore.__set_str_subject("Chinese"); subscore.__set_i_score(85); }else{ subscore.__set_str_subject("English"); subscore.__set_i_score(82); } vec_subscore.push_back(subscore); } stu.__set_list_subscores(vec_subscore); stu.__set_i_uid(1001); stu.__set_str_name("xiaoming"); stu.__set_str_sex("man"); ostringstream out; out.clear(); stu.printTo(out); printf("student: %s
"
, out.str().c_str()); pClient->work_score(retinfo, stu); transport->close(); } // bool InitConfInfo(const std::string& file, string& str_ip, int& port) { CIniFile ini; std::string str_val; if (!ini.Init(file)) { printf("ini init file failed: %s
"
, file.c_str()); return false; } // load config ini.Read_Profile_String("client", "host", str_val); if (!str_val.empty()) str_ip = str_val; else str_ip = "192.168.37.131"; ini.Read_Profile_String("client", "port", str_val); if (!str_val.empty()) port = atoi(str_val.c_str()); else port = 8828; return true; }

Makefileファイル:
#Makefile
OBJECT=./util/publicfunctions.o ./util/inifile.o ./thrift/gen-cpp/StudentServ.o \
        ./thrift/gen-cpp/student_types.o ./thrift/gen-cpp/student_constants.o \

CPP=g++ -g -std=c++11

ITHRIFT=-I./thrift/gen-cpp -I/usr/local/include/thrift/ 
LTHRIFT=/usr/local/thrift/lib/libthrift.a

CFLAGS=-I. -I./util ${ITHRIFT} 
LFLAGS=-pthread -ldl

all: client server

$(OBJECT):%.o:%.cpp
    $(CPP) ${CFLAGS} ${LFLAGS} -c $< -o $@

client.o:%.o:%.cpp
    $(CPP) ${CFLAGS} ${LFLAGS} -c $< -o $@

server.o:%.o:%.cpp
    $(CPP) ${CFLAGS} ${LFLAGS} -c $< -o $@

client:$(OBJECT) client.o
    $(CPP) -o client ${OBJECT}  client.o ${CFLAGS} ${LFLAGS} ${LTHRIFT}

server:$(OBJECT) server.o
    $(CPP) -o server ${OBJECT}  server.o ${CFLAGS} ${LFLAGS} ${LTHRIFT}

clean:
    $(RM) *.o ./util/*.o ./thrift/gen-cpp/*.o  client server
    /usr/local/thrift/bin/thrift -o ./thrift/ --gen cpp ./thrift/student.thrift

実行結果:クライアント:
# ./client 
serverip: 127.0.0.1, port: 8828
student: student(list_subscores=[subjectscore(str_subject=Match, i_score=88), subjectscore(str_subject=Chinese, i_score=85), subjectscore(str_subject=English, i_score=82)], i_uid=1001, str_name=xiaoming, str_sex=man)

サービス:
# ./server 
Server Port:8828
student: student(list_subscores=[subjectscore(str_subject=Match, i_score=88), subjectscore(str_subject=Chinese, i_score=85), subjectscore(str_subject=English, i_score=82)], i_uid=1001, str_name=xiaoming, str_sex=man)
return info:sturesult(i_uid=1001, str_name=xiaoming, str_sex=man, i_subscore=85, i_avescore=0, str_maxsub=Match, str_mixsub=English)
ServerHandler work_score