Я разрабатываю приложение на основе C++ ASIO. Ссылаясь на Chat ServerC++ ASIO: обработчик async_accept() выдает исключение, когда сервер уничтожает
Класса Моего сервера:
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
}
}
Когда мои CServer Object
истребляет, после вызова ~CServer()
Он устанавливает Handle Accept
ошибку потому что существующее по умолчанию прослушивания сеанса активно. И, возвращаясь с handle_accept()
, он выдает исключение.
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.
ниже стек вызовов:
> 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++
У меня был аналогичный вопрос с session class destruction
Asked Here
Как решить эту проблему и обеспечить чистый выход, когда ~CServer()
называется.
Почему вы уничтожаете объект 'CServer', если он все еще прослушивает входящие соединения? –
Существует несколько 'CServer', поэтому, когда выходит из области действия' handle_accept() 'error, генерируется. Это также происходит, если я вызываю 'acceptor_.close()' и возвращаясь из 'handle_accept' - генерируется исключение. Как обеспечить чистое уничтожение «CServer Class» –
в целом, вы гарантируете, что время жизни объекта CServer продолжается до тех пор, пока оно выполняет работу, например, при прослушивании входящих соединений. Обычно это делается путем наследования от 'enable_shared_from_this', некоторые из примеров Asio используют эту концепцию. –