2013-05-15 148 views
5

我使用boost::asio作爲服務器/客戶端應用程序。服務器一次只接受一個連接。我想知道服務器驗證客戶端是否仍然連接的最佳方式是什麼。Boost ASIO:服務器如何知道客戶端是否仍然連接?

這樣做的目的是希望能夠知道客戶端是否崩潰,以便我可以重新啓動偵聽新的連接嘗試。

+0

您需要應用程序級的心跳 - 沒有其他可靠的方法。 –

回答

3

在我的應用程序中,我使用了以下標誌,當客戶端斷開連接時,我的讀取出現。 請在您的應用程序中嘗試。連接後立即應用此標誌。

在我的情況skt_TCP的類型是boost::asio::ip::tcp::socket

int32_t accept_server_socket = skt_TCP.native_handle(); 

int32_t timeout = 8; 
int32_t cnt = 2; 
int32_t intverval = 2; 

// Added Keepalive flag 
boost::asio::socket_base::keep_alive opt_keep_alive(true); 
skt_TCP.set_option(opt_keep_alive); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout)); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPINTVL, &intverval, sizeof(intverval)); 
0

的這實際上取決於您選擇的協議。

簡單的命令協議

如果您的服務器協議始終等待來自客戶端的消息,你將永遠有連接的每個客戶端掛起async_read。當客戶端以任何方式斷開連接時,這應該返回一個錯誤(EOF)。

保持活性是一種如上所述的方法,但等待async_read的工作就此達到目的。

簡單事件協議

一個簡單的事件協議涉及客戶端偵聽數據和服務器發送。在這個協議中,服務器不知道客戶端是否在那裏,因爲客戶端只接受數據並繼續等待。客戶端永遠不會向服務器發送任何消息。

這提出了保持活力的要求。當客戶端已斷開連接時,async_write操作不會以與async_read相同的方式失敗。

還有其他選項,例如讓服務器始終有一個試圖讀取1個字節的未決async_read操作。當客戶端斷開類似於上面的簡單命令協議討論時,這將失敗,但是永遠不會成功,因爲客戶端不通過簡單事件協議發送數據。

相關問題