2017-05-12 4 views
1

Visual Studio 2015를 사용하여 C++로 작성된 매우 간단한 Apache Thrift 서버 및 클라이언트를 실험하고 있습니다.이 코드는 공식 Apache Thrift 샘플을 기반으로합니다.C++로 작성된 Apache Thrift 서버가 TTransportException을 던졌습니다.

최신 버전의 Thrift (0.10.0), Boost (1.64.0) 및 OpenSSL (1.1.0e)을 사용하고 있습니다.

namespace cpp test 

service Test { 
    void ping() 
} 

중고품 컴파일러는 Test.h를 생성

throw TTransportException(TTransportException::END_OF_FILE, "No more data to read."); 

가 여기 내 test.thrift 파일입니다 :

클라이언트에서 서버로 호출 할 때마다 TTransport.h 라인 (43)에 TTransportException를 트리거 이는 아래에 서버와 클라이언트 모두에서 # 포함됩니다 (실제 생성 된 코드는 자동 생성되지 않습니다). 주요

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

using namespace std; 

int main() 
{ 
    boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); 
    boost::shared_ptr<TTransport> transport(new TFramedTransport(socket)); 
    boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 
    test::TestClient client(protocol); 

    try { 
     transport->open(); 

     client.ping(); 
     cout << "ping()" << endl; 

     transport->close(); 
    } 
    catch (TException& tx) { 
     cout << "ERROR: " << tx.what() << endl; 
    } 
    return 0; 
} 

및 서버 :

#include <thrift/protocol/TBinaryProtocol.h> 
#include <thrift/transport/TSocket.h> 
#include <thrift/transport/TTransportUtils.h> 
#include <thrift/server/TSimpleServer.h> 
#include <thrift/transport/TServerSocket.h> 
#include <thrift/transport/TBufferTransports.h> 

#include <Test.h> 

주요 클라이언트 :

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

using namespace std; 

class TestHandler : virtual public test::TestIf { 
public: 
    TestHandler() { 
     // Your initialization goes here 
    } 

    void ping() { 
     // Your implementation goes here 
     printf("ping\n"); 
    } 
}; 


int main() 
{ 
    std::cout << "Starting thrift server thread" << std::endl; 
    int port = 9090; 
    boost::shared_ptr<TestHandler> handler(new TestHandler()); 
    boost::shared_ptr<TProcessor> processor(new test::TestProcessor(handler)); 
    boost::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); 
    boost::shared_ptr<TTransportFactory> transportFactory(new TFramedTransportFactory()); 
    boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); 

    boost::shared_ptr<apache::thrift::server::TSimpleServer> server = boost::shared_ptr< TSimpleServer>(new TSimpleServer(processor, serverTransport, transportFactory, protocolFactory)); 

    server->serve(); 
    return 0; 
} 

가 나는 또한 함께 TBufferedTransport 및 TJSONProtocol를 사용하여 시도

중고품 헤더 파일은 클라이언트와 서버 모두에 포함 같은 결과.

예외가 발생한다는 사실은 이것이 정상적으로 작동하지 않는다는 것을 나타내지 만 호출은 수신되고 처리됩니다 (예외는 TestHandler :: ping() 호출 이후에 발생하며 서버는 계속 수신 대기하고 수신 요청 (매번 같은 오류가 발생 함)이므로 복구 가능한 조건입니다.

왜 이런 일이 일어나고 있는지, 해결할 수있는 것인지, 해결해야 할 것인가, 그리고 그렇지 않은 경우이 예외에도 불구하고 서버를 사용하는 것이 안전한지 궁금합니다.

+0

클라이언트가 연결을 닫을 때 서버 끝에서 처리됩니까? – JensG

+0

예, 그렇습니다. 실제로 더 많은 테스트를 실행했고 클라이언트가 연결을 닫을 때 예상되는 동작이라고 생각하기 시작했습니다. 그러나 예외로 신호를 받았다는 사실이 나를 혼란에 빠지게했습니다. 예를 들어 네트워크 오류로 인해 연결이 닫히면 예외가 발생해야하지만 이것이 "닫기"에 대한 제어되고 명시적인 호출이므로 서버가 예상 한 동작으로 처리해야합니다. – Ady

+0

나는 약간 이상하다. 그렇다. 그렇다. 나는 디자인에서 그 점에 대한 이유가 무엇일 수 있었는지 항상 궁금해했다. 어쩌면 지금 그것을 바꿀 때가되었습니다. – JensG

답변

2

설계 상.

슬리 프 라이브러리는 연결 끝이 TTransportException을 던져 내부적으로 전달되는 방식으로 구현됩니다.