Mam serwer TCP na boost :: asio, nasłuchuje połączenia i po jego uruchomieniu rozpoczyna wysyłanie bloków danych za pomocą instrukcji boost :: asio :: write w pętli.Nie można złapać wyjątku z boost :: asio :: io_service :: uruchom
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}
}
}
Jeśli ręcznie zatrzymam odbiornik, wyjątek dotyczący uszkodzonego przewodu jest generowany i obsługiwany prawidłowo. Ale rura czasami łamane dzieje (przyczynę złego połączenia ja przypuszczam) i wyjątek cudownie spada przez wszystkich połowów, a aplikacja jest rozwiązana:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
Badanie rdzeń widzę, że to się stało w boost :: asio :: write pochodzi z io_service :: run(). Co ja robię źle?
Próbowałem również przepisać serwer TCP za pomocą async_write, ale nadal tak się dzieje, ale nie tak często.
EDIT1: jeśli zatrzymam odbiornik ręcznie powodując uszkodzenie rury, otrzymam dokładnie ten sam wyjątek i dokładnie taki sam odbiór, ale ten, który mogę obsłużyć.
EDIT2: z tego, co rozumiem, teraz wyjątek, którego nie można odczytać, może być wynikiem zbyt dużej ilości danych wysyłanych zbyt szybko przez gniazdo. Nie jestem tego pewien.
Czy jesteś pewien, że jest to wyjątek? Co otrzymasz, jeśli "złapiesz (...)"? – wally
Mam wydruk z napisem "zakończ wywołanie po rzuceniu instancji" boost :: wyjątek_detail :: clone_impl> ' what(): write: Broken pipe ". złapać (...) niczego nie łapie. –
Czy to jest rzucanie z jakiejś funkcji, która ma specyfikację wyjątku? Spójrz na [tę odpowiedź] (http://stackoverflow.com/a/26332289/1460794). – wally