Мое клиентское приложение использует boost::asio::ip::tcp::socket
для подключения к удаленному серверу. Если приложение теряет соединение с этим сервером (например, из-за сбоя сервера или его выключения), я хотел бы, чтобы оно пыталось повторно подключиться через регулярные промежутки времени, пока оно не будет успешным.
Что мне нужно сделать на стороне клиента, чтобы аккуратно обработать отключение, привести в порядок и затем неоднократно повторять попытки подключения?
В настоящее время интересные фрагменты моего кода выглядят примерно так.
Мне connect
нравится это:
bool MyClient::myconnect()
{
bool isConnected = false;
// Attempt connection
socket.connect(server_endpoint, errorcode);
if (errorcode)
{
cerr << "Connection failed: " << errorcode.message() << endl;
mydisconnect();
}
else
{
isConnected = true;
// Connected so setup async read for an incoming message.
startReadMessage();
// And start the io_service_thread
io_service_thread = new boost::thread(
boost::bind(&MyClient::runIOService, this, boost::ref(io_service)));
}
return (isConnected)
}
Где метод runIOServer()
просто:
void MyClient::runIOService(boost::asio::io_service& io_service)
{
size_t executedCount = io_service.run();
cout << "io_service: " << executedCount << " handlers executed." << endl;
io_service.reset();
}
И если какой-либо из обработчиков асинхронного чтения возвращает ошибку, они просто вызывают этот disconnect
метод:
void MyClient::mydisconnect(void)
{
boost::system::error_code errorcode;
if (socket.is_open())
{
// Boost documentation recommends calling shutdown first
// for "graceful" closing of socket.
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode)
{
cerr << "socket.shutdown error: " << errorcode.message() << endl;
}
socket.close(errorcode);
if (errorcode)
{
cerr << "socket.close error: " << errorcode.message() << endl;
}
// Notify the observer we have disconnected
myObserver->disconnected();
}
..который пытается корректно отключиться, а затем уведомляет наблюдателя, который начинает вызывать connect()
с пятисекундными интервалами, пока не восстановит соединение.
Что еще мне нужно сделать?
В настоящее время это похоже работает. Если я убиваю сервер, к которому он подключен, я получаю ожидаемую "End of file"
ошибку в моих обработчиках чтения, и mydisconnect()
вызывается без каких-либо проблем.
Но когда он затем пытается повторно подключиться и терпит неудачу, я вижу отчет "socket.shutdown error: Invalid argument"
. Это просто потому, что я пытаюсь выключить сокет, на котором нет ожидающих чтения / записи? Или это нечто большее?
shutdown()
. В основном я делаю это для простоты: тот же методmydisconnect()
вызывается, если я хочу нормально отключиться или если какие-либо асинхронные операции возвращают ошибку. - person GrahamS   schedule 18.06.2010close()
- это все, что требуется. Данные, которые еще находятся в полете, по-прежнему доставляются. - person user207421   schedule 29.03.2017