通过线程巧为InetAddress.getByName() DNS查询添加超时限制功能

虽然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查询添加了一个2秒的超时时间限制。

简单分析一下是如何做到的:

DNS线程执行InetAddress.getByName()方法向DNS发起查询请求,此时因为网络IO,DNS线程会阻塞,但是由于主线程调用了join,所以主线程不会继续执行。这时会出现2种情况:

1. 网络IO完成,DNS线程继续执行,getByName()方法返回,将包含了目标主机IP的InetAddress对象保存到成员变量中。

2. 网络IO未完成,但是2秒已过,主线程的join()调用返回,主线程继续执行,但是getIP()会返回null,即表示DNS查询失败。


如此一来完美解决了DNS查询超时问题。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
InetAddress.getByName()是Java中的一个方法,用于获取指定主机名或IP地址的InetAddress对象。\[1\]这个方法可以接受一个主机名或IP地址作为参数,并返回对应的InetAddress对象。例如,如果传递给getByName()方法的参数是"www.baidu.com",那么返回的InetAddress对象将表示该主机的IP地址。\[2\]另外,如果传递给getByName()方法的参数是null或"localhost",那么返回的InetAddress对象将表示本地主机的IP地址。\[1\]通过调用InetAddress对象的getHostName()方法,可以获取主机名,而调用getHostAddress()方法可以获取IP地址。\[2\]所以,通过使用InetAddress.getByName()方法,我们可以获取指定主机名或IP地址的InetAddress对象,并进一步获取主机名和IP地址的信息。 #### 引用[.reference_title] - *1* *3* [利用InetAddress.getByName()来产生你的IP地址](https://blog.csdn.net/qq_39061832/article/details/75577282)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[java语言]——InetAddress类的getByName()方法](https://blog.csdn.net/ankki12345/article/details/101943771)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值