У меня есть особенно ужасный кусок сетевого кода. Я использую Asio, но это действительно не имеет значения для этого вопроса. Я предполагаю, что нет другого способа отсоединить сокет, кроме как закрыть его. Проблема в том, что open()
, bind()
и listen()
могут все бросить system_error
. Поэтому я обработал код простым try/catch
. Код, написанный на ломаном.
using namespace boost::asio;
class Thing
{
public:
ip::tcp::endpoint m_address;
ip::tcp::acceptor m_acceptor;
/// connect should handle all of its exceptions internally.
bool connect()
{
try
{
m_acceptor.open( m_address.protocol() );
m_acceptor.set_option( tcp::acceptor::reuse_address(true) );
m_acceptor.bind( m_address );
m_acceptor.listen();
m_acceptor.async_accept( /*stuff*/ );
}
catch( const boost::system::system_error& error )
{
assert(acceptor.is_open());
m_acceptor.close();
return false;
}
return true;
}
/// don't call disconnect unless connect previously succeeded.
void disconnect()
{
// other stuff needed to disconnect is ommited
m_acceptor.close();
}
};
Ошибка в том, что если сокету не удается подключиться, он попытается закрыть его в блоке catch и выдать еще один системный ошибку о закрытии акцептора, который никогда не был открыт.
Одним из решений является добавление if( acceptor.is_open() )
в блок catch, но на вкус это неправильно. Вроде как смешивание проверки ошибок C
в стиле с c++
исключениями. Если я пойду по этому пути, я также могу использовать версию «1014» *.
без броска.
boost::system::error_code error;
acceptor.open( address.protocol, error );
if( ! error )
{
try
{
acceptor.set_option( tcp::acceptor::reuse_address(true) );
acceptor.bind( address );
acceptor.listen();
acceptor.async_accept( /*stuff*/ );
}
catch( const boost::system::system_error& error )
{
assert(acceptor.is_open());
acceptor.close();
return false;
}
}
return !error;
Существует ли элегантный способ обработки этих возможных исключений с использованием блоков RAII и try/catch
?
Я просто ошибаюсь, пытаясь избежать обработки ошибок в стиле if( error condition )
при использовании исключений?