2009-08-13 17 views
2

我有Java代碼,它通過使用C++編寫的服務器的套接字發出請求。通信很簡單,java代碼爲請求寫入一行,然後服務器在響應中寫入一行,但有時候似乎服務器沒有響應,所以我實現了一個基於ExecutorService的超時,它試圖放棄重新啓動連接。如何刪除/重新啓動客戶端連接到片狀套接字服務器

與連接工作,我不斷:

Socket server; 
PrintWriter out; 
BufferedReader in; 

因此,在設置連接的問題:

server = new Socket(hostname, port); 
out = new PrintWriter(new OutputStreamWriter(server.getOutputStream())); 
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

如果不是因爲超時的代碼請求/接收步驟簡單地說:

String request="some request"; 
out.println(request); 
out.flush(); 
String response = in.readLine(); 

當我收到一個超時時,我試圖關閉連接:

in.close(); 
out.close(); 
socket.close(); 

但是其中一個關閉似乎阻止並且不會返回。任何人都可以給我一個線索,爲什麼其中一個會阻止,什麼是放棄連接的正確方式,而不是資源泄漏問題?

回答

0

關閉包裝套接字的緩衝讀寫器將關閉套接字。
關閉一個已經關閉的套接字是不正確的,但它不應該是一個問題。

不管怎樣,根據java socket: 套接字一旦關閉,就無法進一步聯網(即不能重新連接或反彈)。需要創建一個新的套接字。

因此,您需要在關閉此對象後創建一個新的套接字對象。

就你的內存管理而言,垃圾處理程序應該爲你殺掉你的舊垃圾處理程序,所以不要擔心泄漏。

0

對out.close()的調用可能會被阻塞,因爲PrintWriter.close()方法與println(String)方法在同一個鎖上同步。如果原始調用println被阻塞,試圖寫入一個錯誤的連接,你將無法調用close()。

您是否嘗試過使用Socket.setSoTimeout()方法?

+0

我沒有嘗試調用setSoTimeout(),但它聽起來像隻影響讀取調用,如果我在寫入調用中被阻塞(這聽起來像我給out.close()也阻塞)它不會幫助我 - 對嗎? – 2009-08-14 17:36:25

0

我想你只需要關閉套接字(然後相應地處理讀/寫線程中的任何異常)。另外,如上所述,重新創建套接字。

相關問題