我的客户端应用程序使用boost::asio::ip::tcp::socket
连接到远程服务器。 如果应用程序失去与此服务器的连接(例如,由于服务器崩溃或正在关闭),我希望它会定期尝试重新连接,直到成功为止。如何在断开连接后干净地重新连接boost :: 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();
}
..试图恩典完全断开,然后通知观察员,该观察员将以5秒的间隔开始呼叫connect()
,直到重新连接。
还有什么我需要做的吗?
目前确实似乎工作。如果我终止了连接的服务器,则在读取处理程序时出现预期的"End of file"
错误,并且mydisconnect()
被调用时没有任何问题。
但是,当它然后尝试重新连接,并失败,我看到它报告"socket.shutdown error: Invalid argument"
。这是否仅仅是因为我试图关闭一个没有读/写挂起的套接字?还是更多?
如果您已经检测到连接的另一端被关闭,那么调用关机的理由是什么? – 2010-06-17 19:26:32
@samm:这不推荐?我认为可能会有套接字上的挂起操作需要使用shutdown()来取消。我主要只是为了简单起见:如果我想正常断开连接,或者任何异步操作返回错误,则会调用相同的'mydisconnect()'方法。 – GrahamS 2010-06-18 08:09:04
我不确定它是否被推荐。待处理的数据或操作将在哪里进行?连接的另一端不在那里。 – 2010-06-18 11:52:34