当前位置: 首页 > 知识库问答 >
问题:

如何配置主机名解析以在Java中使用自定义DNS服务器?

邹弘
2023-03-14

Java语言网默认情况下,InetAddress使用本地计算机的默认主机名解析程序解析主机名:

主机名到IP地址的解析是通过使用本地机器配置信息和网络命名服务(如域名系统(DNS)和网络信息服务(NIS))的组合来实现的。默认情况下,正在使用的特定命名服务是本地计算机配置的服务。对于任何主机名,都会返回其相应的IP地址[来源]

我们如何在不修改本地机器的默认主机名解析器的情况下配置此行为?

例如,是否有配置java的方法。网InetAddress,以便通过OpenDNS(208.67.222.222208.67.220.220)或谷歌公共DNS(2001:4860:4860::8882001:4860:4860::8844)解析主机名?

或者是显式创建DNS数据包请求、通过java.net.DatagramSocket或java.net.Socket将它们发送到服务器并解析响应的唯一解决方案?

共有3个答案

顾学真
2023-03-14

对于高达8的Java版本,以下是我编写的代码,用于在Java中硬编码afoo系统名称DNS解析,以通过测试用例。它的意思是将您的特定条目附加到默认Java运行时DNS解析。

我建议不要在生产中运行它。使用了强制反射访问和Java运行时非公共实现类!

private static final String FOO_IP = "10.10.8.111";

/** Fake "foo" DNS resolution */
@SuppressWarnings("restriction")
public static class MyHostNameService implements sun.net.spi.nameservice.NameService {
    @Override
    public InetAddress[] lookupAllHostAddr(String paramString) throws UnknownHostException {
        if ("foo".equals(paramString) || "foo.domain.tld".equals(paramString)) {
            final byte[] arrayOfByte = sun.net.util.IPAddressUtil.textToNumericFormatV4(FOO_IP);
            final InetAddress address = InetAddress.getByAddress(paramString, arrayOfByte);
            return new InetAddress[] { address };
        } else {
            throw new UnknownHostException();
        }
    }
    @Override
    public String getHostByAddr(byte[] paramArrayOfByte) throws UnknownHostException {
        throw new UnknownHostException();
    }
}

static {
    // Force to load fake hostname resolution for tests to pass
    try {
        List<sun.net.spi.nameservice.NameService> nameServices =
            (List<sun.net.spi.nameservice.NameService>)
            org.apache.commons.lang3.reflect.FieldUtils.readStaticField(InetAddress.class, "nameServices", true);
        nameServices.add(new MyHostNameService());
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

希望这有帮助,但再次,小心使用!

莘翰采
2023-03-14

具有以下接口并允许访问java。净值*可以将自己的DNS提供程序与JDK8和JDK9一起使用。新的提供者是通过“INameService.install(new MyNameService());”安装的

public interface INameService extends InvocationHandler {
    public static void install(final INameService dns) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
        final Class<?> inetAddressClass = InetAddress.class;
        Object neu;
        Field nameServiceField;
        try {
            final Class<?> iface = Class.forName("java.net.InetAddress$NameService");
            nameServiceField = inetAddressClass.getDeclaredField("nameService");
            neu = Proxy.newProxyInstance(iface.getClassLoader(), new Class<?>[] { iface }, dns);
        } catch(final ClassNotFoundException|NoSuchFieldException e) {
            nameServiceField = inetAddressClass.getDeclaredField("nameServices");
            final Class<?> iface = Class.forName("sun.net.spi.nameservice.NameService");
            neu = Arrays.asList(Proxy.newProxyInstance(iface.getClassLoader(), new Class<?>[] { iface }, dns));
        }
        nameServiceField.setAccessible(true);
        nameServiceField.set(inetAddressClass, neu);
    }

    /**
     * Lookup a host mapping by name. Retrieve the IP addresses associated with a host
     *
     * @param host the specified hostname
     * @return array of IP addresses for the requested host
     * @throws UnknownHostException  if no IP address for the {@code host} could be found
     */
    InetAddress[] lookupAllHostAddr(final String host) throws UnknownHostException;

    /**
     * Lookup the host corresponding to the IP address provided
     *
     * @param addr byte array representing an IP address
     * @return {@code String} representing the host name mapping
     * @throws UnknownHostException
     *             if no host found for the specified IP address
     */
    String getHostByAddr(final byte[] addr) throws UnknownHostException;

    @Override default public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
        switch(method.getName()) {
        case "lookupAllHostAddr": return lookupAllHostAddr((String)args[0]);
        case "getHostByAddr"    : return getHostByAddr    ((byte[])args[0]);
        default                 :
            final StringBuilder o = new StringBuilder();
            o.append(method.getReturnType().getCanonicalName()+" "+method.getName()+"(");
            final Class<?>[] ps = method.getParameterTypes();
            for(int i=0;i<ps.length;++i) {
                if(i>0) o.append(", ");
                o.append(ps[i].getCanonicalName()).append(" p").append(i);
            }
            o.append(")");
            throw new UnsupportedOperationException(o.toString());
        }
    }
}
米浩穰
2023-03-14

Java9删除了此功能。您需要使用第三方DNS客户端库。

如果您使用的是Java 8或更高版本,您可以执行以下操作:

您可以设置本网站记录的系统属性sun.net.spi.nameservice.nameservers

 类似资料:
  • 问题内容: 默认情况下,java.net.InetAddress使用本地计算机的默认主机名解析器解析主机名: 主机名到IP地址的解析是通过结合使用本地计算机配置信息和网络命名服务(例如域名系统(DNS)和网络信息服务(NIS))来完成的。 默认情况下, 使用的特定命名服务是 本地计算机配置的一个 。对于任何主机名,将返回其相应的IP地址。[资源] 我们如何在不修改本地计算机的默认主机名解析器的情况

  • 让dhcp服务器收集到的主机名 加入 dns服务中? 尝试过dnsmasq这个集成了 dhcp和dns服务器的软件,但是在网上搜索时,没发现这样的用法. 尝试把 建立一个ddns服务,然后让每台电脑 进行 动态域名注册 ,但是这样每台电脑都需要配置,感觉有点麻烦 最终期望

  • DNS记录主要用于将域名转换为托管本网站的服务器IP。 记录是在域名注册商处输入的,这一点很重要。 他们通常为您提供一个DNS管理器面板。 主要目的是人员和应用程序不必记住大数字来导航到一个域。 例如,www.yiibai.com 的IP为 ,所以记住一个友好的名字更容易。 指向一个域的IP是通过一个记录完成的。 例如:www.yiibai.com A记录为 还有其他类型的DNS记录用于网页,具体

  • 4.2 DNS域名解析配置信息 由于iOS平台无法获取到移动设备上的首选和备用DNS域名解析的服务器的IP地址,而Android平台能够获取到;所以iOS和Android平台SDK在处理获取域名解析服务器IP地址上有所不同。Android平台是直接从设备上获取得到DNS域名解析服务器的IP地址,而iOS平台则是从VPN下发的配置信息中取出与VPN相关的域名解析服务器IP地址,分别作为各自的平台的D

  • 问题内容: 我在组成2.9(在yml版本2.1中)的“自定义”桥网络中的“ Ubuntu 16.10服务器”上运行多个容器。我的大多数容器在内部都使用相同的端口,因此我无法使用“主机”网络驱动程序。我的容器都是通过专用属性链接在一起的。 但是,我还需要访问容器外部公开的服务。这些服务具有专用URL,其名称已在我公司的DNS服务器中注册。虽然我可以使用公共DNS并从容器中访问任何公共服务没有问题,但

  • 问题内容: Roderic DM Page博士在有关 生命科学标识符的论文 (请参阅LSID Tester,该工具用于测试生命科学标识符解析服务 )中说: 鉴于LSID瓮:LSID : ubio.org:namebank:11815,查询该SRV记录的DNS __lsid.tcp 。 **ubio.org** 返回animalia.ubio.org:80作为ubio.org LSID服务的位置。