将TCP套接字连接到主机名时发生捕获超时异常
我需要捕获与主机名和端口的TCP连接的超时异常,其中包括对主机名进行DNS查找。如果我连接到数字IP地址和端口,我可以设置一个短暂超时并快速捕获异常,但如果使用域名,DNS查找可能需要5分钟时间来引发异常。将TCP套接字连接到主机名时发生捕获超时异常
如何使此操作超时更快?
Socket socketconnectionObjet = new Socket();
socketconnectionObjet.connect(new InetSocketAddress(url, port),
3 * 1000);
看一看:Socket#connect。您请求功能在5分钟后失败(3 * 1000
)。阅读提供的文档以获取更多信息。
不正确。您自己的链接显示超时时间以毫秒为单位。 – 2015-02-23 12:51:36
首先,了解实际需要超时两个单独的进程 - 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