Java:JAVA API域名解析说明

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)

相关推荐
架构师沉默9 小时前
别又牛逼了!AI 写 Java 代码真的行吗?
java·后端·架构
后端AI实验室13 小时前
我把一个生产Bug的排查过程,交给AI处理——20分钟后我关掉了它
java·ai
凉年技术15 小时前
Java 实现企业微信扫码登录
java·企业微信
狂奔小菜鸡16 小时前
Day41 | Java中的锁分类
java·后端·java ee
hooknum17 小时前
学习记录:基于JWT简单实现登录认证功能-demo
java
程序员Terry17 小时前
同事被深拷贝坑了3小时,我教他原型模式的正确打开方式
java·设计模式
NE_STOP17 小时前
MyBatis-缓存与注解式开发
java
码路飞17 小时前
不装 OpenClaw,我用 30 行 Python 搞了个 QQ AI 机器人
java
Re_zero18 小时前
以为用了 try-with-resources 就稳了?这三个底层漏洞让TCP双向通讯直接卡死
java·后端
SimonKing18 小时前
Fiddler抓包完全指南:从安装配置到抓包,一文讲透
java·后端·程序员