Ho un server TCP su boost :: asio, ascolta una connessione e dopo averlo inizia a inviare blocchi di dati usando boost :: asio :: write in un ciclo.Impossibile rilevare l'eccezione da boost :: asio :: io_service :: eseguire
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}
}
}
Se si arresta manualmente un ricevitore, un'eccezione relativa al tubo rotto viene generata e gestita correttamente. Ma tubo talvolta accade rotture (causa di cattiva connessione suppongo) e l'eccezione miracolosamente cade attraverso tutte le catture e l'applicazione viene terminata:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
Esaminando il nucleo vedo che è accaduto a boost :: asio :: scrivere originato in io_service :: run(). Che cosa sto facendo di sbagliato?
Inoltre, ho provato a riscrivere il server TCP utilizzando async_write, ma succede ancora, non così spesso però.
EDIT1: se il ricevitore viene interrotto manualmente causando un guasto del tubo, ottengo la stessa identica eccezione e lo stesso callstack ma questo posso gestirlo.
EDIT2: da quello che ho capito ora l'eccezione non intercettabile può essere il risultato di troppi dati inviati troppo velocemente attraverso il socket. Non sono sicuro però.
Sei sicuro che sia un'eccezione? Cosa ottieni se prendi (...) '? – wally
Ho una stampa che dice "termina chiamata dopo aver lanciato un'istanza di 'boost :: exception_detail :: clone_impl>' what(): write: Broken pipe ". prendere (...) non cattura nulla. –
Si sta lanciando da qualche funzione che ha una specifica di eccezione? Dai un'occhiata a [questa risposta] (http://stackoverflow.com/a/26332289/1460794). – wally