当前位置: 动力学知识库 > 问答 > 编程问答 >

C++ ASIO: async_accept() handler throws exception when server destroys

问题描述:

I am developing a C++ ASIO based application. Referring to Chat Server

My Server Class:

class CServer {

public:

CServer(asio::io_service& io_service, const std::string serIdentity, std::string IP, const std::string port);

~CServer();

void listen();

void handle_accept(sessionPtr newSession, const asio::error_code& error);

private:

tcp::acceptor acceptor_; // only in the listener

asio::io_service& io_;

CSerSessionsManager mng_;

};

void CServer::listen()

{

sessionPtr newSession = std::make_shared<channel::CSerSession>(io_, mng_, serIdentifier_, ip_, port_);

acceptor_.async_accept(newSession->socket(), std::bind(&CServer::handle_accept, this, newSession,

std::placeholders::_1));

}

void CServer::handle_accept(sessionPtr newSession, const asio::error_code& error)

{

if (!error)

{

//Do Something

listen();

}

else

{

DEBUG_MSG("Listen_Error");

//Returning from here throws Exception

}

}

When my CServer Object destroys, after calling ~CServer() It sets Handle Accept error because an existing default listening session is active. And while returning from handle_accept() it throws exception.

Unhandled exception at 0x74E8C42D in channel.exe: Microsoft C++ exception: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::system_error> > at memory location 0x023EF3EC.

below is the call stack:

> channel.exe!boost::throw_exception<std::system_error>(const std::system_error & e) Line 69 C++

channel.exe!asio::detail::do_throw_error(const std::error_code & err) Line 32 C++

channel.exe!asio::detail::throw_error(const std::error_code & err) Line 34 C++

channel.exe!asio::io_service::run() Line 59 C++

channel.exe!boost::_mfi::mf0<unsigned int,asio::io_service>::operator()(asio::io_service * p) Line 49 C++

channel.exe!boost::_bi::list1<boost::_bi::value<asio::io_service *> >::operator()<unsigned int,boost::_mfi::mf0<unsigned int,asio::io_service>,boost::_bi::list0>(boost::_bi::type<unsigned int> __formal, boost::_mfi::mf0<unsigned int,asio::io_service> & f, boost::_bi::list0 & a, long __formal) Line 244 C++

channel.exe!boost::_bi::bind_t<unsigned int,boost::_mfi::mf0<unsigned int,asio::io_service>,boost::_bi::list1<boost::_bi::value<asio::io_service *> > >::operator()() Line 21 C++

channel.exe!asio::detail::win_thread::func<boost::_bi::bind_t<unsigned int,boost::_mfi::mf0<unsigned int,asio::io_service>,boost::_bi::list1<boost::_bi::value<asio::io_service *> > > >::run() Line 116 C++

channel.exe!asio::detail::win_thread_function(void * arg) Line 109 C++

I had similar issue with session class destruction Asked Here

How do I resolve this and ensure clean exit when ~CServer() is called.

网友答案:

I'd suggest having a look at the various HTTP Server Examples for Boost ASIO as they are more complete than the chat example.

One pattern that works for shutdown of a server object is to have a handle_stop method that closes the acceptor and shuts down the connections, e.g. the following from the single-threaded HTTP Server Example linked above:

void server::handle_stop()
{
  // The server is stopped by cancelling all outstanding asynchronous
  // operations. Once all operations have finished the io_service::run() call
  // will exit.
  acceptor_.close();
  connection_manager_.stop_all();
}

In the Boost example, this is called by a Ctrl-C handler:

  // Register to handle the signals that indicate when the server should exit.
  // It is safe to register for the same signal multiple times in a program,
  // provided all registration for the specified signal is made through Asio.
  signals_.add(SIGINT);
  signals_.add(SIGTERM);
#if defined(SIGQUIT)
  signals_.add(SIGQUIT);
#endif // defined(SIGQUIT)
  signals_.async_wait(boost::bind(&server::handle_stop, this));

But you might want to shut-down explicitly from a stop method, like:

void server::stop()
{
    io_service_.post(boost::bind(&server::handle_stop, this));
}

If you need more advice on how to hook that in, we'll need to see the rest of your ASIO code.

分享给朋友:
您可能感兴趣的文章:
随机阅读: