我需要捕获到主机名和端口的TCP连接的超时异常,其中包括对主机名进行DNS查找。如果我连接到数字IP地址和端口,我可以设置短暂超时并快速捕获异常,但如果我使用域名,DNS查找可能需要5分钟才能抛出异常。
如何更快地暂停此操作?
Socket socketconnectionObjet = new Socket();
socketconnectionObjet.connect(new InetSocketAddress(url, port),
3 * 1000);
答案 0 :(得分:0)
看看:Socket#connect。您请求该函数在5分钟后失败(3 * 1000
)。阅读提供的文档以获取更多信息。
答案 1 :(得分: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在Windows上阻止了一些反向DNS调用4.5秒)。
一种解决方案是简单地避免使用Java的本机DNS查找实用程序,并使用支持超时的外部库,DnsJava' SimpleResolver具有{ {3}}方法。
另一个想到的解决方案是在单独的线程中执行DNS查找,并等待该线程使用具有超时值的setTimeout()或Thread.join()来完成其业务。如果第二个线程及时完成,请使用剩余时间进行连接。如果它没有,并且您在Thread.join
或Future.get
上超时,那么您已超时。