2010-07-29 61 views
7

使用java.net.Socket.connect()時,拒絕連接和超時都會導致ConnectException區分連接被拒絕和連接超時

java.net.ConnectException: Connection timed out: connect 

java.net.ConnectException: Connection refused: connect 

我該如何安全區分這兩者?肯定解析錯誤消息來完成這項工作。但是當這個消息在未來的Java版本中發生變化時,我倒黴了。

大圖:我正在使用帶有Metro實現的JAX-WS編寫web服務客戶端。當Web服務調用失敗時,我想清楚地報告失敗原因,以便快速解決問題。

回答

2

不幸的是,在Sun JDK中,除了字符串之外,這個信息在任何地方都不可用。請參閱PlainSocketImpl.c(用於* ix)和net_util_md.c(用於Windows)的第473行。 * ix實現有時會調用NET_ThrowByNameWithLastError(來自* ix net_util_md.c),這將在字符串中包含errno;此功能在Windows上存在,但此處未使用..

因此,您必須依賴字符串並希望它們不會更改。 Sun似乎並沒有將它們本地化,這是有道理的,因爲它們不應該是面向用戶的。您可以嘗試解析errno以獲得更穩定的錯誤代碼。

如果沒有字符串或errno匹配,您還應該確保有一個回退。

+0

回退是一個可接受的解決方案。 – 2010-07-29 15:22:05

+0

我喜歡這個答案,但保持我以前的建議:將其抽象化!你想要做的最後一件事是在你不能依賴的界面上進行一系列不一致和重複的檢查。創建一個對你有意義的界面,並將細節抽象出來。如果有任何更改,您不想編輯一打文件。 – riwalk 2010-07-30 03:51:08

0

檢查錯誤信息(就像你提到的),但將其抽象出來。

如果它在未來的Java發行版中發生變化,您可以在抽象中對其進行更改,並保留代碼的核心。

+1

如果JVM具有本地化的消息,則會立即中斷。 – 2010-07-29 14:27:40

3

測量調用connect()和拋出異常之間傳遞的時間,並傳遞該信息。