![](/img/trans.png)
[英]Socket not closing serverside when calling socket.close() in client JAVA
[英]Anything I can do when socket.close() throws in Java?
一周前開始學習 java 並決定學習處理異常的正確方法。 Java 真的讓我很生氣,因為指定方法可以拋出異常作為其簽名的一部分。
我目前正在嘗試為客戶端-服務器應用程序實現多線程服務器。 我對socket.close()
可以拋出 IOException 的事實感到非常驚訝。 問題是,如果發生這種情況我該怎么辦?
...
final Socket socket = .... // at this point I know that I have a good socket
try {
..... // communicating with someone on that side....
} catch(IOException e) {
// communication failed
// this fact is useful, I can log it
// and will just hang up
} finally {
try {
socket.close(); // bye-bye
} catch(IOException e) {
// anything but logging I can do here?
}
}
...
這段代碼在一個單獨的線程中執行,所以我只需要捕獲所有的異常。 問題主要是心理上的——我知道,我可以把catch
塊留空,但我試圖避免這個把戲。
有什么想法嗎?
當關閉資源失敗時,您不做任何重大的事情是很常見的。 記錄可能是一個好主意,這樣您就有機會了解它是否更頻繁地發生。
如果關閉資源也是“提交”或以其他方式保持更改,這是不同的:那么您需要像對待任何其他部分的異常一樣對待它:處理它。
請注意,Java 7 專門引入了自動資源管理來簡化這些類型的結構。 如果您現在學習 Java,那么我建議您使用最新最好的。
我想這取決於您是從套接字讀取數據還是向其寫入數據。 如果您讀取數據並檢索到您想要的所有信息,那么您可以放心地忽略該異常。 但是,如果您編寫數據,您可能不得不假設它沒有正確傳輸。
Apache Commons IO (一個我幾乎無法編寫 Java 的庫)有一個方法IOUtils.closeQuietly()
僅用於此目的
所以你可以這樣做:
final Socket socket = .... // at this point I know that I have a good socket
try {
..... // communicating with someone on that side....
} catch(IOException e) {
// communication failed
// this fact is useful, I can log it
// and will just hang up
} finally {
IOUtils.closeQuietly(socket);
}
並為自己節省 5 行代碼。
作為獎勵,如果套接字是 null 或已經關閉, closeQuietly()
會做正確的事情。 其他任何Closeable
的東西也有重載。
正如評論中所說,您在那里無能為力。 我建議你無論如何都要記錄一個錯誤,這樣如果它真的發生了,你至少有一個地方可以開始尋找。
這引起了很多人的注意,強制捕獲這樣的嵌套異常。
你應該記錄它,理想情況下使用像 Log4J 這樣強大的東西,但否則我會說忽略它是安全的,除了評論說“故意忽略”。
除了捕獲並記錄它之外,您無法處理 close 引發的異常。 重要的是,如果你讓它被拋出,並且如果在到達 close 方法之前拋出了另一個異常,那么 close 方法可能會拋出一個異常來掩蓋第一個異常,它不會出現任何地方,你都不會知道真正的問題是什么。 所以你絕對不想要那個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.