当前位置: 首页 > 面试题库 >

Windows上的DNS反向查询会阻塞几秒钟,以获取无法解析的IP地址

景轶
2023-03-14
问题内容

我正在使用Java InetAddress.getHostName()执行一些反向DNS查找,并且花费的时间似乎有些问题。这是一个代码片段:

public static void main(String[] args) throws IOException {

byte[][] addresses = new byte[][] { { 10, (byte) 0, (byte) 0, (byte) 138 }
    , new byte[] { (byte) 216, (byte) 239, (byte) 49, (byte) 245 }
    ,{ 8, (byte) 8, (byte) 8, (byte) 8 } };

    for (byte[] addr : addresses) {
        InetAddress inet = InetAddress.getByAddress(addr);
        long before = System.currentTimeMillis();
        String hostName = inet.getHostName();
        System.out.printf("%20s %40s %5d\n", inet.getHostAddress(), hostName, (System.currentTimeMillis() - before));
    }
}

这是我机器上的输出:

    10.0.0.138                               10.0.0.138  4503
216.239.49.245                           216.239.49.245  4591
       8.8.8.8           google-public-dns-a.google.com     8

不管我运行这段代码的次数如何,解析10.0.0.138和216.239.49.245都需要4.5秒。所有无法解析的IP地址似乎都发生了这种情况。

这不是网络问题,因为根据Wireshark捕获, 除非先清除DNS缓存,否则* 甚至 在运行此代码时 都不会发送
DNS查询(然后结果甚至更慢-每个分辨率大约4.7秒)。
*

那么,针对操作系统的本地DNS缓存超时实际上需要Java
4.5秒吗?这是没有意义的。命令行实用程序nslookup以更快的速度返回这些IP地址的结果(无法解析),它甚至不使用缓存!

有人可以解释这种现象并提出加快这些解决方案的方法吗?我唯一想到的不用外部库就是使用多个线程,因此至少4.5秒的超时将并行执行。

供参考,我在Windows 7 x64上使用JDK 7u71

编辑:

这似乎是Windows问题。在同一LAN中使用完全相同的DNS并在JDK 1.7u67上运行OpenSuse 13.1的计算机返回以下结果:

没有DNS缓存:

10.0.0.138                                   10.0.0.138  116             
216.239.49.245                           216.239.49.245  5098             
8.8.8.8                  google-public-dns-a.google.com  301

使用DNS缓存:

10.0.0.138                                   10.0.0.138  5
216.239.49.245                           216.239.49.245  9             
8.8.8.8                  google-public-dns-a.google.com  40

编辑3:

最终,我不得不通过使用dnsjava进行自己的反向DNS查找来解决此问题。


问题答案:

Windows中的DNS客户端实现似乎有问题。我只是在C#.NET中尝试了相同的逻辑:

 static void Main(string[] args)
    {
        byte[][] addresses = new byte[][] { new byte[] { 10, (byte) 0, (byte) 0, (byte) 138 },
            new byte[] { (byte) 216, (byte) 239, (byte) 49, (byte) 245 },
            new byte []{ 8, (byte) 8, (byte) 8, (byte) 8 } };
        foreach (byte[] addr in addresses)
        {
            IPAddress inet = new IPAddress(addr);
            DateTime before = DateTime.Now;
            String hostName = null;
            try
            {
                hostName = System.Net.Dns.GetHostByAddress(inet).HostName;
            }
            catch { }
            finally
            {
                DateTime after = DateTime.Now;
                Console.WriteLine("{0} {1} {2}", inet.ToString(), hostName!=null?hostName:"N/A", after.Subtract(before));
            }
        }
        Console.ReadLine();
    }

这些是结果:

   10.0.0.138 N/A 00:00:04.5604560
   216.239.49.245 N/A 00:00:04.7984798
   8.8.8.8 google-public-dns-a.google.com 00:00:00.0060006

有趣的是,在刷新DNS缓存后,Windows将所有DNS请求发送到网络。DNS服务器在0.25秒后回复,但如果回答是“ No Such
Name”,则DNS客户端在整个超时时间内仍会阻塞。



 类似资料:
  • 问题内容: 有没有一种干净的方法可以以Java异步,非阻塞的方式(例如,状态机,而不是1个查询= 1个线程)来解析DNS查询(通过主机名获取IP)-我想同时运行数万个查询,但是不能运行数万个线程)? 到目前为止,我发现了什么: 标准实现正在阻塞,并且看起来标准Java库缺少任何非阻塞实现。 批量解决DNS问题也讨论了类似的问题,但是找到的唯一解决方案是多线程方法(即,一个线程在每个给定的时间段内仅

  • 我明白任何客户端应用程序请求查询域名将发送到DNS服务器域名到IP解析。但是如果请求的查询只是IP地址,这是否意味着该查询不会发送到DNS服务器进行解析?我想知道客户机应用程序是否会决定节省到DNS服务器的行程?请指教。谢谢!!

  • 我可以使用下面的curl命令获得重定向的url。 但我有一个案例,页面加载200状态,但在2或3秒后,页面被重定向。Curl给我的原始url的响应是200,但在等待几秒钟后会发生301重定向。 有没有办法让卷曲追踪出最后的重定向?

  • 问题内容: 我想从Swift中的DNS查询中获取IP地址(例如192.168.0.1或87.12.56.50)。我用100种不同的方法尝试了100次…没有任何帮助,所以我必须寻求帮助。到目前为止,这是我的代码: 问题答案: 您的代码将地址检索为“套接字地址”结构。 可用于将地址转换为数字IP字符串回收的代码,现已更新为Swift 2 ): 输出(示例): 还要注意第一行的用法,因为名称中 带有“

  • 我想编辑bashrc文件,让它有一个简单的函数“myip”来运行。正如您可能猜到的,函数myip只打印我的计算机的内部IP地址。 我正在研究Mac ;OS ;X。 我怎么才能完成这件事?

  • demo import java.io.IOException; import java.net.*; /**  * 查找IP地址  */ public class TestFindDNS {   public static void main(String[] args) throws IOException {     //     String href = "http://