首先,瞭解實際需要超時兩個單獨的進程 - 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查找實用程序,並使用支持超時的外部庫,例如DnsJava的SimpleResolver,它具有setTimeout()方法。
想到的另一個解決方案是在單獨的線程中執行DNS查找,然後等待該線程使用帶有超時值的Thread.join()或Future.get()完成其業務。如果第二個線程及時完成,請使用剩餘時間進行連接。如果沒有,並且您在Thread.join
或Future.get
上超時,則表示超時。
+1這不是一個微不足道的問題,因爲它聽起來,因爲它是DNS查找,而不是隨後的套接字操作超時。也許你可以明確地進行DNS查詢,首先? – 2015-02-23 12:53:27