如何判斷socket客戶端斷開

我寫了一個socket的客戶端和服務器端,請問服務器端如何判斷客戶端已經斷開連接了
如果客戶端結束進程,會發出FIN,但是如果是網線撥了,服務器就不知道了。借樓主的貼討論一下:
1.如果撥掉網線的時候服務哭正在阻塞讀,且沒有設置超時選項,它會阻塞多久才能知道不可達?
2.如果。。。。。。。。。。正在阻塞寫,。。。。。。。。。。。。。。。。。。。。。。。?
(也沒有設置KEEP_ALIVE)
我用心跳機制來防止拔網線這中情況
client每間隔M秒發一個心跳包給server
若連續N秒server端沒有收到client的心跳包,則認爲client已經去見馬克思了

一般應該這樣:

1、心跳。
2、非阻塞方式。阻塞方式是不方便判斷諸如:網線斷開這樣的異常情況的。說“不方便”,就因爲還是依賴於程序的實現是怎麼樣的。
QUOTE:
原帖由 linuxxinetd 於 2007-8-21 20:22 發表
進程是這樣可以的。但我用的是線程,客戶端和服務器端都有兩個收發線程,客戶端發送線程退出,服務器的收線程怎麼知道啊?


服務器的收線程的 recv函數會返回0

------------------------------------------------------------------------
最近在開發中遇到一個問題,就是如何判斷遠端服務器是否已經斷開連接,如果斷開那麼需要重新連接。

首先想到socket類的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但經過試驗並查看相關文檔,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連接。

然後想到是否可以通過OutputStream發送一段測試數據,如果發送失敗就表示遠端已經斷開連接,類似ping,但是這樣會影響到正常的輸出數據,遠端無法把正常數據和測試數據分開。

最後又回到socket類,發現有一個方法sendUrgentData,查看文檔後得知它會往輸出流發送一個字節的數據,只要對方Socket的SO_OOBINLINE屬性沒有打開,就會自動捨棄這個字節,而SO_OOBINLINE屬性默認情況下就是關閉的,太好了,正是我需要的!

於是,下面一段代碼就可以判斷遠端是否斷開了連接:

try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章