java中判斷socket伺服器端是否斷開連線
首先想到socket類的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但經過試驗並檢視相關文件,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連線。
然後想到是否可以通過OutputStream傳送一段測試資料,如果傳送失敗就表示遠端已經斷開連線,類似ping,但是這樣會影響到正常的輸出資料,遠端無法把正常資料和測試資料分開。
最後又回到socket類,發現有一個方法sendUrgentData,檢視文件後得知它會往輸出流傳送一個位元組的資料,只要對方Socket的SO_OOBINLINE屬性沒有開啟,就會自動捨棄這個位元組,而SO_OOBINLINE屬性預設情況下就是關閉的,太好了,正是我需要的!
於是,下面一段程式碼就可以判斷遠端是否斷開了連線:
try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
}
用ping實現
package com.csdn.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class test {
static BufferedReader bufferedReader;
public static void main(String[] args) throws IOException {
try {
Process process = Runtime.getRuntime().exec("ping 192.168.1.104");//判斷是否連線的IP;
bufferedReader = new BufferedReader(new InputStreamReader(process
.getInputStream()));
String connectionStr = "";
while ((connectionStr = bufferedReader.readLine()) != null) {
System.out.println(connectionStr);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
bufferedReader.close();
}
}
}
ping的方法有個嚴重的BUG,就是你只能判斷對方是否連線網路,而不能判斷客戶端是否開啟...
我在寫聊天室時經常要注意客戶端異常退出的問題(比如客戶直接呼叫工作管理員結束程式程序),
其實在通過socket.getoutstream和socket.getinputstream流對客戶端傳送、接受資訊時如果socket沒連線上是會丟擲異常的,這也就是為什麼Java會要求網路程式設計都要寫在try裡面,所以只要在catch裡面寫入客戶端退出的處理就行了,沒必要專門去想什麼方法