InetAddress可以表示无法解析的主机名吗?

时间:2010-10-30 17:57:10

标签: java networking

我用其中的网络信息解析各种数据源。

我一直在使用java.net.InetAddress来表示和解析主机。使用IP初始化它可以正常工作。

我现在必须解析一个新的来源。它包含主机名而不是IP。如果无法将主机名参数解析为IP,则InetAddress.getByName()将抛出UnknownHostException。主机IP对我的目标来说并不是绝对必要的。仅因DNS故障而丢弃数据对我来说是不可接受的。

如果可以获得IP地址或者其他主机名,我想拥有一个IP地址。

如何阻止解析给定的主机名?还有另一个课程更适合我的需求吗?

5 个答案:

答案 0 :(得分:2)

方法InetAddress.getByAddress(String host, byte[] addr)不会对DNS执行查询,并允许您创建具有任意主机名和IP地址的InetAddress,可能是IPv4未指定的地址(0.0.0.0)。

尝试使用InetAddress创建getByName,如果它被抛出,您可以使用getByAddress创建它。请注意,在实际使用IP地址之前,您需要检查IP地址是否有效。


示例代码:

  public static void main(String arg[])
    throws  UnknownHostException
  {
    InetAddress a;
    byte[] unspec = new byte[4];
    unspec[0]=0;
    unspec[1]=0;
    unspec[2]=0;
    unspec[3]=0;
    try
    {
      a = InetAddress.getByName(arg[0]);
    }
    catch(UnknownHostException e)
    {
      a = InetAddress.getByAddress(arg[0],unspec);
    }
    System.out.println(a);
  }

答案 1 :(得分:1)

我想这是不可能的,因为InetAddress的核心功能是处理IP地址:

  

此类代表Internet   协议(IP)地址。

     

IP地址是32位或   IP使用的128位无符号数,a   低级协议   建立了UDP和TCP等协议。   定义了IP地址架构   RFC 790:Assigned Numbers,RFC   1918年:私人地址分配   互联网,RFC 2365:行政上   范围内的IP组播和RFC 2373:IP   版本6寻址架构。一个   InetAddress的实例包含   一个IP地址,可能还有它   相应的主机名(取决于   它是否由主机构建   名称或是否已经完成   反向主机名解析。)

您无法构建没有IP地址的InetAddress对象。

为了您的目的,您需要定义一个Hostname.class,它包含主机名和可能的其他数据。如果您使用的是Java 6,则此类应该/可以通过IDN处理所有域名国际化。如果您使用的是Java 5,则可以使用单独的IDN库。

单独的Hostname.class还可以定义防护或构造函数,它们根据相关的RFC确保只有有效的主机名。

答案 2 :(得分:0)

写一堂课怎么样?它只需要能够存储String和InetAddress。

答案 3 :(得分:0)

通过编辑/etc/hosts文件解决问题:

我也有类似的问题(InetAddress.getByName无法使用主机名。)

我通过仅使用127.0.0.1 localhost删除::1 localhostff81::1%lo0 localhost等条目来解决此问题。

我删除了localhost的其余条目。我为我的Mac做了这个。

有时,我给出的任何信息都无效。在这种情况下,我只是将文件/ etc / hosts文件移动到hosts_backup。然后恢复了文件。即将文件hosts_backup移动到/ etc / hosts。然后它开始工作。不知道它是如何工作的。但它解决了我的问题

答案 4 :(得分:-1)

我刚刚使用InetAddress类进行了一些实验,并且还阅读了它的javadoc。

在第一次触摸后,我可以告诉我在两种情况下得到UnknownHostException:当我通过非法格式化字符串(例如http://stackoverflow.com而不是stackoverflow.com)或者当我传递URL时也无法在浏览器中解析(例如aosjdfk23423.com)。

这两种情况都记录在javadocs中(虽然没有任何关于参数格式的严格说明)。这里有相关的javadocs部分:

  

主机名可以是机器名,例如        java.sun.com,或其文字表示         IP地址。如果提供了文字IP地址,则仅提供         检查地址格式的有效性。

  

@exception UnknownHostException如果没有IP地址                 可以找到host,或者指定了scope_id              用于全局IPv6地址。

要点:

这有效:

InetAddress.getByName("google.com");
InetAddress.getByName("74.125.87.99");

并抛出UnknownHostException

InetAddress.getByName("http://google.com");
InetAddress.getByName("unexistingresourse234234.com");

UPD(作为评论的答案:应该有类似的东西:

List<String> hosts = getPossibleHosts(); //these are all hosts you want to transform into inet addresses
final List<InetAddress> inetAddresses = new LinkedList<InetAddress>();
final List<String> badHosts = new LinkedList<String>();

for(String host : hosts) {
    try {
        inetAddresses.add(InetAddress.getByName(host));
    } catch (UnknownHostException e) {
        badHosts.add(host);
    }
}

之后,您可以根据需要处理两个列表。但尝试将它们放在同一个列表中是错误的 - 它们并不相同。