2015-02-23 52 views
1

我需要捕獲與主機名和端口的TCP連接的超時異常,其中包括對主機名進行DNS查找。如果我連接到數字IP地址和端口,我可以設置一個短暫超時並快速捕獲異常,但如果使用域名,DNS查找可能需要5分鐘時間來引發異常。將TCP套接字連接到主機名時發生捕獲超時異常

如何使此操作超時更快?

Socket socketconnectionObjet = new Socket(); 
socketconnectionObjet.connect(new InetSocketAddress(url, port), 
           3 * 1000);   
+0

+1這不是一個微不足道的問題,因爲它聽起來,因爲它是DNS查找,而不是隨後的套接字操作超時。也許你可以明確地進行DNS查詢,首先? – 2015-02-23 12:53:27

回答

0

看一看:Socket#connect。您請求功能在5分鐘後失敗(3 * 1000)。閱讀提供的文檔以獲取更多信息。

+0

不正確。您自己的鏈接顯示超時時間以毫秒爲單位。 – 2015-02-23 12:51:36

0

首先,瞭解實際需要超時兩個單獨的進程 - DNS查找和連接本身很重要。如果既要滿足一定的超時時間內,則該解決方案必須是這個樣子:

long startTime = System.currentTimeMillis(); 
InetAddress destination = doDnsLookupWithTimeout(MAX_TIMEOUT); 
long remaniningTime = MAX_TIMEOUT - (System.currentTimeMillis() - startTime); 
if (remainingTime > 0){ //we still have time to connect 
    connectWithTimeout(remainingTime); 
} 

好消息是,它很容易超時套接字連接,你已經這樣做了。不過壞消息是,強制執行DNS查詢超時更困難。不幸的是,Java的InetAddress.getByName()不接受超時參數,因此呼叫可能會阻塞很長一段時間(我最近用had an issue阻止了4.5秒的窗口反向DNS調用)。

一個解決方案是簡單地避免Java的本機DNS查找實用程序,並使用支持超時的外部庫,例如DnsJavaSimpleResolver,它具有setTimeout()方法。

想到的另一個解決方案是在單獨的線程中執行DNS查找,然後等待該線程使用帶有超時值的Thread.join()Future.get()完成其業務。如果第二個線程及時完成,請使用剩餘時間進行連接。如果沒有,並且您在Thread.joinFuture.get上超時,則表示超時。

相關問題