标签:
虽然Socket类有setTimeout()方法,URLConnection有setConnectTimeout()方法,但这都不能给DNS查询过程添加时间限制,也就是说,如果DNS服务器挂了,那么代码就会阻塞几十秒才能抛出异常。我最近就遇到了这个问题,当DNS服务器出问题的时候,setTimeout()设置的超时时间就不起作用了。
经过google,发现Java目前居然还没有现成的API来处理DNS查询超时的问题。不过一个老外的博客上给出了一种曲线救国的方法:
public class DNSLookupThread extends Thread { private InetAddress addr; private String hostname; public DNSLookupThread(String hostname) { this.hostname = hostname; } public void run() { try { InetAddress add = InetAddress.getByName(hostname); set(add); } catch (UnknownHostException e) { } } private synchronized void set(InetAddress addr) { this.addr = addr; } public synchronized String getIP() { if (null != this.addr) { return addr.getHostAddress(); } return null; } }
DNSQuery dnsTh = new DNSQuery(); dnsTh.start(); dnsTh.join(2000); System.out.println(dnsTh.get())
简单分析一下是如何做到的:
DNS线程执行InetAddress.getByName()方法向DNS发起查询请求,此时因为网络IO,DNS线程会阻塞,但是由于主线程调用了join,所以主线程不会继续执行。这时会出现2种情况:
1. 网络IO完成,DNS线程继续执行,getByName()方法返回,将包含了目标主机IP的InetAddress对象保存到成员变量中。
2. 网络IO未完成,但是2秒已过,主线程的join()调用返回,主线程继续执行,但是getIP()会返回null,即表示DNS查询失败。
如此一来完美解决了DNS查询超时问题。
通过线程巧为InetAddress.getByName() DNS查询添加超时限制功能
标签:
原文地址:http://blog.csdn.net/neosmith/article/details/43235335