我製作了一個具有客戶端和服務器端的Java應用程序。雙方通過套接字進行通信。這個效果很好,直到我的服務器應用程序被某些事情殺死,並且無法關閉或關閉serversocket。Java在客戶端檢測與服務器的斷開
客戶端似乎沒有注意到斷開的連接,只是在嘗試讀取下一個對象時掛起。
我也試着每隔5秒從客戶端發送一個測試對象來檢測服務器是否脫機,但這也不起作用。
我可能不得不說這隻發生在運行Windows上的服務器應用程序和Linux上的客戶端(Ubuntu VirtualBox中)時。 Windows-Windows工作正常。儘管我已經殺死了服務器,但Netstat甚至給了我一個建立在Linux上的ESTABLISHED。
客戶端代碼:
requestSocket = new Socket("192.168.1.3", 1234);
out = new ObjectOutputStream(new CipherOutputStream(requestSocket.getOutputStream(), ec));
in = new ObjectInputStream(new CipherInputStream(requestSocket.getInputStream(), dc));
new Thread() {
public void run() {
while(true) {
try {
out.writeObject(obj);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("sent");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
}
}
}.start();
Server代碼:
serverSocket = new ServerSocket(1234);
socket = serverSocket.accept();
out = new ObjectOutputStream(new CipherOutputStream(clientSocket.getOutputStream(), ec));
in = new ObjectInputStream(new CipherInputStream(clientSocket.getInputStream(), dc));
//do-while-reading on the socket[...]
我讀多線程它告訴我如何檢測在服務器端失去聯繫,但沒有發現任何的客戶端或答案不適合我。
從我的理解,如果服務器端偵聽套接字仍然綁定,或者應用程序沒有實際完全退出時崩潰,如果它有端口應該已被釋放OS或子進程的服務器仍在運行。如果後者是真的,那麼即使綁定它的進程已經終止,它仍然可以綁定端口,因爲子進程仍在運行。你的服務器產生子進程嗎?如果服務器實際已退出,則應通過嘗試寫入套接字客戶端上的outputstream來收到異常。 – 2014-10-09 19:34:12
關閉服務器應用程序後,Windows上的Netstat不顯示任何連接。所以我猜這個港口不再受限制了,對嗎? 另外,是的,我通過javafx爲每個新連接產生一個子線程/任務。 – blkchockr 2014-10-09 19:56:33
@blkchockr當有數據要發送時,Windows [可以保持連接打開](http://superuser.com/a/217353/156822)。你測試過Linux-Linux嗎? – nemo 2014-10-09 20:35:54