2016-05-26 26 views
9

私はboost :: asioにTCPサーバーを持っています。接続を待ち受けてから、boost :: asio :: writeを使ってデータブロックを送信し始めます。ループで。boost :: asio :: io_service :: runから例外をキャッチできません

bool TcpServer::StartTcpServer(std::shared_ptr<boost::asio::io_service> io_service) 
{ 
    m_ioservice = io_service; 
    m_acceptor.reset(new boost::asio::ip::tcp::acceptor(*m_ioservice, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port))); 
    m_socket = std::unique_ptr<boost::asio::ip::tcp::socket>(new boost::asio::ip::tcp::socket(*m_ioservice)); 

    m_socket->close(); 
    m_acceptor->async_accept(*m_socket, m_peer_endpoint, boost::bind(&TcpServer::AcceptHandler, this, boost::asio::placeholders::error)); 

    m_io_thread.reset(new std::thread([this]{ 
    try 
    { 
     this->m_ioservice->run(); 
    } 
    catch(const boost::system::system_error & err){print logs} 
    catch(...){print another logs} 
    })); 
} 

void TcpServer::AcceptHandler(const boost::system::error_code &ec) 
{ 
    while(true) 
    { 
     try 
     { 
      boost::asio::write(*m_socket, boost::asio::buffer(data->c_str(), data->size()), boost::asio::transfer_all()); 
     } 
     catch(const boost::system::system_error & err){print logs} 
     catch(...){print another logs} 
    } 
} 

受信者を手動で停止すると、破損したパイプに関する例外がスローされ、正しく処理されます。しかし、時には壊れたパイプは、奇跡的にすべての漁獲を通って落下し、アプリケーションを終了する(私は仮定接続不良の原因)と、例外を発生します。

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >' 

私はそれがブーストで起こっていることがわかりコアを調べる:: ASIO ::書き込みはio_service :: run()で始まります。私は間違って何をしていますか?

また、私はasync_writeを使用してTCPサーバーを書き直そうとしましたが、まだそれほど頻繁には起こりません。

EDIT1:受信機を手動で停止させてパイプを破損させた場合、まったく同じ例外とまったく同じ呼び出しスタックが得られますが、これを処理できます。

EDIT2:私が今理解しているところから、あまりにも多くのデータがあまりにも速くソケットを介して送信されたために捕捉できない例外が発生する可能性があります。確かに。

+0

本当に例外ですか?あなたが 'キャッチ(...)'すれば何を得ますか? – wally

+0

私は "boost :: exception_detail :: clone_impl のインスタンスをスローした後に呼び出されて終了しました"という出力を持っています。 what():write:壊れたパイプ" catch(...)は何も捕まえません。 –

+0

例外仕様を持つ関数から投げられていますか? [この回答](http://stackoverflow.com/a/26332289/1460794)を見てください。 – wally

答えて

1

エラーメッセージterminateには、実際に何が起こっているか説明しています。 boost::exception_detail::clone_implが失敗しています。コードを掘り下げることなく、私はそれが例外クラスのコピーコンストラクタを実装するために使用されていると思います。このコピーコンストラクタが例外処理中に例外をスローすると、例外ブロックをバイパスし、例外が上方に伝播します。 (参照によってキャッチしても、コンパイラによってコピーが作成されている可能性があります)。なぜコピーコンストラクタが失敗しているのですか。知っている質問には十分ではありません。しかし、非同期I/Oに関連するthis questionは非常によく似た問題を抱えていましたが、例外処理の前にshared_ptrが破棄されていたようです。同じように見えます。

関連する問題