我的客户端应用程序使用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()
方法。 - GrahamSclose()
是所需的全部。仍在传输中的数据仍将被传递。 - user207421