java中获取dns结果
提供两种方法获取域名解析的结果
1.使用Process启动一个进程
private List<String> getDigResults(String host,String server){
InputStream is = null;
BufferedReader br = null;
Process p=null;
StringBuffer sbf = new StringBuffer();
try {
String cmd= MessageFormat.format("dig @{0} {1} +short",server,host);
p = Runtime.getRuntime().exec(cmd);
p.waitFor();
is = p.getInputStream();
br = new BufferedReader(new InputStreamReader(is,"utf-8"));
String tmp = "";
while((tmp = br.readLine())!=null){
sbf.append(tmp+",");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
IOUtils.closeQuietly(br);
IOUtils.closeQuietly(is);
p.destroy();
return Arrays.asList(sbf.toString().split(","));
}
}
实质就是运行了dig命令获取执行结果
2.使用dnsjava
添加maven依赖
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>2.1.8</version>
</dependency>
dnsjava是完全线程化的,推荐使用
Resolver resolver = new SimpleResolver("114.114.114.114");
Lookup lookup = new Lookup("www.baidu.com",Type.A);
lookup.setResolver(resolver);
Cache cache=new Cache();
lookup.setCache(cache);
lookup.run();
if(lookup.getResult()==Lookup.SUCCESSFUL){
Record[] records=lookup.getAnswers();
for (Record record:records){
System.out.println(record.rdataToString());
}
}
以上代码可以获取域名解析的A记录,值得注意的是
工具支持直接查询CNAME,只需声明
Lookup lookup = new Lookup("www.baidu.com",Type.CNAME);
但是这种方法只能获取第一次解析的CNAME.如果像获取类似于dig的解析结果:
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> @114.114.114.114 www.baidu.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18548
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 112 IN CNAME www.a.shifen.com.
www.a.shifen.com. 181 IN A 180.97.33.108
www.a.shifen.com. 181 IN A 180.97.33.107
;; Query time: 23 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Thu Feb 28 18:25:35 2019
;; MSG SIZE rcvd: 90
无法通过方法直接获得,但是我们可以思考既然他可以直接获取A记录,那必然存在一个完成的解析过程,最终获取解析的A记录,经过查看源码发现其将其解析的每一步都存在一个名为cache的Map结构里,也就是说cache就是我们要的结果,比较坑的是作者对cache变量申明成了私有变量也不提供get支持,庆幸的是toString()被覆盖了,不然只能用反射的方法获取了。下面的代码就是获取解析整个过程的代码:
Resolver resolver = new SimpleResolver("114.114.114.114");
Lookup lookup = new Lookup("www.baidu.com",Type.A);
lookup.setResolver(resolver);
Cache cache=new Cache();
lookup.setCache(cache);
lookup.run();
if(lookup.getResult()==Lookup.SUCCESSFUL){
String[] results=cache.toString().split("\n");
for(String result:results){
System.out.println(result);
}
}
结果如下:
{ www.baidu.com. 285 IN CNAME [www.a.shifen.com.] } cl = 3
{ www.a.shifen.com. 189 IN A [115.239.210.27] [115.239.211.112] } cl = 3