我的客戶端應用程序使用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