无法从boost :: asio :: io_service :: run

时间:2016-05-26 12:27:39

标签: c++ boost boost-asio

我在boost :: asio上有一个TCP服务器,它监听连接,并在获取后开始使用boost :: asio :: write在循环中发送数据块。

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> >'

检查核心我发现它发生在boost :: asio :: write中,起源于io_service :: run()。我做错了什么?

此外,我尝试使用async_write重写TCP服务器,但它仍然会发生,但不会经常发生。

EDIT1:如果我手动停止接收器导致管道损坏,我会得到完全相同的异常和完全相同的callstack,但这个我可以处理。

EDIT2:根据我的理解,现在不可捕获的异常可能是因为过多的数据通过套接字发送得太快。但不确定。

1 个答案:

答案 0 :(得分:1)

terminate中的错误消息确实解释了发生了什么。 boost::exception_detail::clone_impl失败了。在不深入研究代码的情况下,我假设它用于实现异常类的复制构造函数。如果此复制构造函数在异常处理期间抛出异常,它将绕过异常块,异常将向上传播。 (即使您通过引用捕获,仍可由编译器进行复制。)

现在我不知道为什么复制构造函数失败了;知道问题还不够。但是与异步I / O相关的this question有一个非常相似的问题,而且问题的关键似乎是在异常处理之前销毁了shared_ptr。看起来很相似。