2017-05-12 2 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)を使用しています。

クライアントからサーバーへの各呼び出しはTTransport.hライン43でTTransportExceptionをトリガー:

namespace cpp test 

service Test { 
    void ping() 
} 

倹約コンパイラがTEST.Hを生成します。

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

ここに私のtest.thriftファイルですサーバーとクライアントの両方で#includeされます(実際に生成されたコードは表示されません)。

倹約ヘッダファイルは、クライアントとサーバーの両方に含ま

:メイン

#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; 

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; 
} 

とサーバメイン:

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

はい、私のテストはそのような場合を示しています。私は実際にもっと多くのテストを実行しました。クライアントが接続を閉じたときにこれが予想される動作だと思っていますが、例外として通知されているという事実がわかりました。私は、例えばネットワークエラーのために接続が閉じた場合に例外がスローされるべきであることを理解していますが、これは "close"への制御された明示的な呼び出しであり、 – Ady

+0

私は同意します、それは少し奇妙ですが、はい、そうです。私はいつもそのデザインのその理由が何であったのか疑問に思った。たぶん今それを変更する時です。 – JensG

答えて

2

デザインによって。

スリフトライブラリは、接続の末尾がTTransportExceptionをスローすることで内部的に通知される方法で実装されます。

関連する問題