开发者

Can InetAddress represent host names that can't be resolved?

I parse various data sources with network info开发者_高级运维rmation in them.

I have been using java.net.InetAddress to represent and parse hosts. It works fine being initialized with IP.

I have to parse a new source now. It contains hostnames instead of IP's. InetAddress.getByName() throws UnknownHostException if a hostname argument can't be resolved to an IP. Host IP isn't absolutely neccessary for my goal. Dropping the data just because of DNS failure is unacceptable for me.

I'd like to have an IP address if it is obtainable or a hostname otherwise.

How do I prevent resolve of given hostnames? Is there another class that is more suited for my needs?


The method InetAddress.getByAddress(String host, byte[] addr) does not perform a query to the DNS and allows you to create an InetAddress having arbitrary hostname and IP address, possibly the IPv4 unspecified address (0.0.0.0).

Try creating the InetAddress with getByName, if it throws you can create it by using getByAddress. Note that you will need to check the IP addresses are valid before actually using them.


Example code:

  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);
  }


I guess that this is not possible, because the core function of InetAddress is to handle IP-Addresses:

This class represents an Internet Protocol (IP) address.

An IP address is either a 32-bit or 128-bit unsigned number used by IP, a lower-level protocol on which protocols like UDP and TCP are built. The IP address architecture is defined by RFC 790: Assigned Numbers, RFC 1918: Address Allocation for Private Internets, RFC 2365: Administratively Scoped IP Multicast, and RFC 2373: IP Version 6 Addressing Architecture. An instance of an InetAddress consists of an IP address and possibly its corresponding host name (depending on whether it is constructed with a host name or whether it has already done reverse host name resolution).

You have no possibility to construct an InetAddress object without an IP-address.

For you purpose you need to define a Hostname.class, which holds the hostname and maybe additional data. This class should/can handle all the domainname internationalization via IDN, if you are using Java 6. There are separate IDN libraries available if you are on Java 5.

A separate Hostname.class can also define guards or constructors, which assure only valid hostnames according to the relevant RFCs.


How about writing a new class? It would only need to be able to store a String and an InetAddress.


Resolved Issue by editing /etc/hosts file:

I also had similar issue (InetAddress.getByName not working with hostname).

I resolved it by removing entries like ::1 localhost, ff81::1%lo0 localhost with only 127.0.0.1 localhost.

I removed rest of the entries for localhost. I did this for my Mac.

Sometime, what ever information that I given is not working. In that case, I just moved the file /etc/hosts file to hosts_backup. then restored the file. ie moved file hosts_backup to /etc/hosts. then it starts working. Don't know how it is working. But it resolved my issue


I've just made some experiments with InetAddress class and also read its javadocs.

After the first touch I can tell that I get UnknownHostException in 2 cases: either when I pass illegal formated string (like http://stackoverflow.com instead of stackoverflow.com) or when I pass URL that cannot be resolved in browser too (i.e. something like aosjdfk23423.com).

Both cases are documented in javadocs (although it's not explicitely said anywhere anything strict about the parameter format). Here are related javadocs parts:

The host name can either be a machine name, such as java.sun.com, or a textual representation of its IP address. If a literal IP address is supplied, only the validity of the address format is checked.

@exception UnknownHostException if no IP address for the host could be found, or if a scope_id was specified for a global IPv6 address.

Summary:

this works:

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

and this throws UnknownHostException:

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

UPD (as an answer to the comments: there should be something like this:

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);
    }
}

After that you can process both lists as you wish. But it's a mistake to try to put them in the same list - they are not same.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜