将TCP套接字连接到主机名时发生捕获超时异常

问题描述:

我需要捕获与主机名和端口的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

看一看:Socket#connect。您请求功能在5分钟后失败(3 * 1000)。阅读提供的文档以获取更多信息。

+0

不正确。您自己的链接显示超时时间以毫秒为单位。 – 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查找实用程序,并使用支持超时的外部库,例如DnsJavaSimpleResolver,它具有setTimeout()方法。

想到的另一个解决方案是在单独的线程中执行DNS查找,然后等待该线程使用带有超时值的Thread.join()Future.get()完成其业务。如果第二个线程及时完成,请使用剩余时间进行连接。如果没有,并且您在Thread.joinFuture.get上超时,则表示超时。