java常用的域名解析的方式是使用InetAddress中的如下2个方法:
InetAddress.getByName(String host);
InetAddress.getAllByName(String host);
以上方法的最大问题是不知道有几个域名服务器,以及IP是从哪个域名服务器解析出来的。
可以通过下面的代码先获取域名服务器的地址,然后从这些域名服务器分别获取解析出来的IP:
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class DnsTester {
// 获取默认的DNS服务器
public static String[] getDnsNameServerUrlArray() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
env.put(Context.PROVIDER_URL, "dns://");
try {
DirContext ctx = new InitialDirContext(env);
String dndUrls = (String) ctx.getEnvironment().get(Context.PROVIDER_URL);
System.out.println(dndUrls);
return dndUrls.split(" ");
} catch (NamingException e) {
e.printStackTrace();
}
return new String[0];
}
// 使用DNS服务器解析域名
public static Map<String, List<String>> getIpList(String domainName) {
Map<String, List<String>> resultMap = new LinkedHashMap<>();
for (String dnsUrl : getDnsNameServerUrlArray()) {
List<String> results = new ArrayList<>();
try {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
env.put(Context.PROVIDER_URL, dnsUrl);
DirContext ctx = new InitialDirContext(env);
Attributes attrs = ctx.getAttributes(domainName, new String[] { "A" });
for (NamingEnumeration<? extends Attribute> e = attrs.getAll(); e.hasMoreElements();) {
Attribute a = e.nextElement();
int size = a.size();
for (int i = 0; i < size; i++) {
results.add((String) a.get(i));
}
}
resultMap.put(dnsUrl, results);
System.out.println(dnsUrl + ": DNS resolve OK");
} catch (NamingException e) {
System.out.println(dnsUrl + ": " + e.getMessage());
}
}
return resultMap;
}
public static void main(String[] args) throws NamingException {
String domainName = "baidu.com";
if (args.length > 0) {
domainName = args[0];
}
Map<String, List<String>> ipList = getIpList(domainName);
System.out.println(domainName + ": " + ipList);
}
}
执行命令
java DnsTester 163.com
运行的结果如下:
dns://25.11.1.3 dns://25.11.1.4 dns://221.179.155.161 dns://221.179.155.177
dns://25.11.1.3: DNS name not found [response code 3]
dns://25.11.1.4: DNS name not found [response code 3]
dns://221.179.155.161: DNS resolve OK
dns://221.179.155.177: DNS resolve OK
163.com: {dns://221.179.155.161=[123.58.180.8, 123.58.180.7], dns://221.179.155.177=[123.58.180.7, 123.58.180.8]}
参考文档
DNS Service Provider for the Java Naming Directory Interface (JNDI)