文档章节

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

SuShine
 SuShine
发布于 2017/01/05 14:50
字数 437
阅读 139
收藏 0

虽然Socket类有setTimeout()方法,URLConnection有setConnectTimeout()方法,但这都不能给DNS查询过程添加时间限制,也就是说,如果DNS服务器挂了,那么代码就会阻塞几十秒才能抛出异常。我最近就遇到了这个问题,当DNS服务器出问题的时候,setTimeout()设置的超时时间就不起作用了。

 

经过google,发现Java目前居然还没有现成的API来处理DNS查询超时的问题。不过一个老外的博客上给出了一种曲线救国的方法:

 

[java] view plain copy

 print?在CODE上查看代码片派生到我的代码片

  1. public class DNSLookupThread extends Thread {  
  2.     private InetAddress addr;  
  3.     private String hostname;  
  4.       
  5.     public DNSLookupThread(String hostname) {  
  6.         this.hostname = hostname;  
  7.     }  
  8.       
  9.     public void run() {  
  10.         try {  
  11.             InetAddress add = InetAddress.getByName(hostname);  
  12.             set(add);  
  13.         } catch (UnknownHostException e) {  
  14.         }  
  15.     }  
  16.       
  17.     private synchronized void set(InetAddress addr) {  
  18.         this.addr = addr;  
  19.     }  
  20.       
  21.     public synchronized String getIP() {  
  22.         if (null != this.addr) {  
  23.             return addr.getHostAddress();  
  24.         }  
  25.           
  26.         return null;  
  27.     }  
  28. }  


类的使用方法如下:

 

 

[java] view plain copy

 print?在CODE上查看代码片派生到我的代码片

  1. DNSQuery dnsTh = new DNSQuery();  
  2.         dnsTh.start();  
  3.         dnsTh.join(2000);  
  4.           
  5.         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查询超时问题。

本文转载自:http://blog.csdn.net/neosmith/article/details/43235335

SuShine
粉丝 130
博文 607
码字总数 159294
作品 0
朝阳
后端工程师
私信 提问
pfSense book之DNS解析

pfSense中的DNS解析利用unbound,这是一个验证、递归、缓存DNS解析器,支持DNSSEC和各种选项。当前版本的pfSense默认启用DNS解析。 默认情况下,DNS解析程序不使用在“系统”>“常规设置”下...

鐵血男兒
2018/01/08
0
0
面向基础系列之---Java网络编程---网络连接组件的使用(InetAddress)

这个系列是我一直想写的,因为从入职第一年的第一个月开始(那时还在zte),我就买了网络上唯一的一本,写Java网络的书籍:《Java网络编程》。当时功底一般,感觉看起来,还是很多云里雾里,...

心中的理想乡
2018/09/10
50
0
tomcat 9.0.4 性能调优a

tomcat 9.0.4 性能调优 295631788 2018-04-23 来源:51CTO tomcat9.0.4 参考了网上的一些优化参数,但是在启动中发现 有2个报错: 参考官方文档 最后修改如下: 参数说明: org.apache.coyot...

linjin200
01/11
15
0
开源DNS服务器软件出现严重漏洞,大家都升级了吗

近期发现法国网络与信息安全局ANSSI发布了升级开源DNS递归解析软件的提醒,此漏洞还挺严重的,国内很多DNS服务器都采用开源软件,特将原文翻译,分享给大家: 法国网络与信息安全局(ANSSI)...

tk777
2014/12/26
1K
0
kubernetes的timeout问题

kubernetes+alpine+php特别容易出现访问外网/解析外网地址的时候出现超时的问题. 原因 docker容器访问外网的时候,整个完整路径是这样的. 容器-->主机-->外网-->主机-->容器 容器到主机之间的...

zeusro
05/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL 11.3 locking

rudi
今天
5
0
Mybatis Plus sql注入器

一、继承AbstractMethod /** * @author beth * @data 2019-10-23 20:39 */public class DeleteAllMethod extends AbstractMethod { @Override public MappedStatement injectMap......

一个yuanbeth
今天
11
1
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
今天
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
今天
9
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
今天
81
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部