6.1 The InetAddress Class
The java.net.InetAddress class is Java's
high-level representation of an IP address, both IPv4 and IPv6. It is used
by most of the other networking classes, including
Socket, ServerSocket,
URL, DatagramSocket,
DatagramPacket, and more. Generally, it includes
both a hostname and an IP address.
public class InetAddress extends Object implements Serializable
|
6.1.1 Creating New InetAddress Objects
There are no public constructors in
the InetAddress class. However,
InetAddress has three static methods that return
suitably initialized InetAddress objects given a
little information. They are:
public static InetAddress getByName(String hostName)All three of these methods may make a connection to the local DNS
throws UnknownHostException
public static InetAddress[] getAllByName(String hostName)
throws UnknownHostException
public static InetAddress getLocalHost( )
throws UnknownHostException
server to fill out the information in the
InetAddress object, if necessary. This has a
number of possibly unexpected implications, among them that these
methods may throw security exceptions if the connection to the DNS
server is prohibited. Furthermore, invoking one of these methods may
cause a host that uses a PPP connection to dial into its provider if
it isn't already connected. The key thing to
remember is that these methods do not simply use their arguments to
set the internal fields. They actually make network connections to
retrieve all the information they need. The other methods in this
class, such as getAddress( ) and
getHostName( ), mostly work with the information
provided by one of these three methods. They do not make network
connections; on the rare occasions that they do, they do not throw
any exceptions. Only these three methods have to go outside Java and
the local system to get their work done.Since DNS lookups can be relatively expensive (on the order of
several seconds for a request that has to go through several
intermediate servers, or one that's trying to
resolve an unreachable host) the InetAddress class
caches the results of lookups. Once it has the address of a given
host, it won't look it up again, even if you create
a new InetAddress object for the same host. As
long as IP addresses don't change while your program
is running, this is not a problem.Negative results (host not found errors) are slightly more
problematic. It's not uncommon for an initial
attempt to resolve a host to fail, but the immediately following one
to succeed. What has normally happened in this situation is that the
first attempt timed out while the information was still in transit
from the remote DNS server. Then the address arrived at the local
server and was immediately available for the next request. For this
reason, Java only caches unsuccessful DNS queries for 10 seconds.In Java 1.4 and later, these times can be controlled by the
networkaddress.cache.ttl and
networkaddress.cache.negative.ttl system
properties. networkaddress.cache.ttl specifies the
number of seconds a successful DNS lookup will remain in
Java's cache.
networkaddress.cache.negative.ttl is the number of
seconds an unsuccessful lookup will be cached. Attempting to look up
the same host again within these limits will only return the same
value. -1 is interpreted as "never
expire".Besides locale caching inside the InetAddress
class, the local host, the local domain name server, and other DNS
servers elsewhere on the Internet may also cache the results of
various queries. Java provides no way to control this. As a result,
it may take several hours for the information about an IP address
change to propagate across the Internet. In the meantime, your
program may encounter various exceptions, including
UnknownHostException,
NoRouteToHostException, and
ConnectException, depending on the changes made to
the DNS.Java 1.4 adds two more factory methods that do not check their
addresses with the local DNS server. The first creates an
InetAddress object with an IP address and no
hostname. The second creates an InetAddress object
with an IP address and a hostname.
public static InetAddress getByAddress(byte[] address)Unlike the other three factory methods, these two methods make no
throws UnknownHostException // 1.4
public static InetAddress getByAddress(String hostName, byte[] address)
throws UnknownHostException // 1.4
guarantees that such a host exists or that the hostname is correctly
mapped to the IP address. They throw an
UnknownHostException only if a byte array of an
illegal size (neither 4 nor 16 bytes long) is passed as the
address argument.
6.1.1.1 public static InetAddress getByName(String hostName) throws UnknownHostException
InetAddress.getByName( ) is the most frequently used of these
factory methods. It is a static method that takes the hostname
you're looking for as its argument. It looks up the
host's IP address using DNS. Call
getByName( ) like this:
java.net.InetAddress address =If you have already imported the
java.net.InetAddress.getByName("www.oreilly.com");
java.net.InetAddress class, which will almost
always be the case, you can call getByName( ) like
this:
InetAddress address = InetAddress.getByName("www.oreilly.com");In the rest of this book, I assume that there is an
import java.net.*; statement at
the top of the program containing each code fragment, as well as any
other necessary import statements.The InetAddress.getByName( ) method throws an
UnknownHostException if the host
can't be found, so you need to declare that the
method making the call throws UnknownHostException
(or its superclass, IOException) or wrap it in a
try block, like this:
try {Example 6-1 shows a complete program that creates an
InetAddress address = InetAddress.getByName("www.oreilly.com");
System.out.println(address);
}
catch (UnknownHostException ex) {
System.out.println("Could not find www.oreilly.com");
}
InetAddress object for www.oreilly.com and prints it out.
Example 6-1. A program that prints the address of www.oreilly.com
import java.net.*;Here's the result:
public class OReillyByName {
public static void main (String[] args) {
try {
InetAddress address = InetAddress.getByName("www.oreilly.com");
System.out.println(address);
}
catch (UnknownHostException ex) {
System.out.println("Could not find www.oreilly.com");
}
}
}
% java OReillyByNameOn rare occasions, you will need to connect to a machine that does
www.oreilly.com/208.201.239.36
not have a hostname. In this case, you can pass a
String containing the dotted quad or hexadecimal
form of the IP address to InetAddress.getByName(
):
InetAddress address = InetAddress.getByName("208.201.239.37");Example 6-2 uses the IP address for www.oreilly.com instead of the name.
Example 6-2. A program that prints the address of 208.201.239.37
import java.net.*;Here's the result in Java 1.3 and earlier:
public class OReillyByAddress {
public static void main (String[] args) {
try {
InetAddress address = InetAddress.getByName("208.201.239.37");
System.out.println(address);
}
catch (UnknownHostException ex) {
System.out.println("Could not find 208.201.239.37");
}
}
}
% java OReillyByAddressWhen you call getByName( ) with an IP address
www.oreilly.com/208.201.239.37
string as an argument, it creates an InetAddress
object for the requested IP address without checking with DNS. This
means it's possible to create
InetAddress objects for hosts that
don't really exist and that you
can't connect to. The hostname of an
InetAddress object created from a string
containing an IP address is initially set to that string. A DNS
lookup for the actual hostname is performed only when the hostname is
requested, either explicitly via getHostName( ) or
implicitly through toString( ).
That's how www.oreilly.com was determined from the
dotted quad address 208.201.239.37. If at the time the hostname
is requested and a DNS lookup is finally performed the host with the
specified IP address can't be found, then the
hostname remains the original dotted quad string. However, no
UnknownHostException is thrown.The toString( ) method in Java 1.4 behaves a
little differently than in earlier versions. It does not do a reverse
name lookup; thus, the host is not printed unless it is already
known, either because it was provided as an argument to the factory
method or because getHostName( ) was invoked. In
Java 1.4, Example 6-2 produces this output:
/208.201.239.37Hostnames are much more stable than IP addresses. Some services have
lived at the same hostname for years but have switched IP addresses
several times. If you have a choice between using a hostname like
www.oreilly.com or an IP address
like 208.201.239.37, always
choose the hostname. Use an IP address only when a hostname is not
available.
6.1.1.2 public static InetAddress[ ] getAllByName(String hostName) throws UnknownHostException
Some computers have more than one Internet address. Given a hostname,
InetAddress.getAllByName() returns an array that contains all the
addresses corresponding to that name. Its use is straightforward:
InetAddress[] addresses = InetAddress.getAllByName("www.apple.com");Like InetAddress.getByName( ),
InetAddress.getAllByName( ) can throw an
UnknownHostException, so you need to enclose it in
a try block or declare that your method throws
UnknownHostException. Example 6-3
demonstrates by returning a complete list of the IP addresses for
www.microsoft.com.
Example 6-3. A program that prints all the addresses of www.microsoft.com
import java.net.*;Here's the result:
public class AllAddressesOfMicrosoft {
public static void main (String[] args) {
try {
InetAddress[] addresses =
InetAddress.getAllByName("www.microsoft.com");
for (int i = 0; i < addresses.length; i++) {
System.out.println(addresses[i]);
}
}
catch (UnknownHostException ex) {
System.out.println("Could not find www.microsoft.com");
}
}
}
% java AllAddressesOfMicrosoftwww.microsoft.com appears to have
www.microsoft.com/63.211.66.123
www.microsoft.com/63.211.66.124
www.microsoft.com/63.211.66.131
www.microsoft.com/63.211.66.117
www.microsoft.com/63.211.66.116
www.microsoft.com/63.211.66.107
www.microsoft.com/63.211.66.118
www.microsoft.com/63.211.66.115
www.microsoft.com/63.211.66.110
nine IP addresses. Hosts with more than one address are the exception
rather than the rule. Most hosts with multiple IP addresses are very
high-volume web servers. Even in those cases, you rarely need to know
more than one address.
6.1.1.3 public static InetAddress getByAddress(byte[ ] address) throws UnknownHostException // Java 1.4public static InetAddress getByAddress(String hostName, byte[] address) throws UnknownHostException // Java 1.4
In Java 1.4 and later, you can pass a byte array and optionally a
hostname to getByAddress() to create an
InetAddress object with exactly those bytes.
Domain name lookup is not performed. However, if byte array is some
length other than 4 or 16 bytesthat is, if it
can't be an IPv4 or IPv6 addressan
UnknownHostException is thrown.This is useful if a domain name server is not available or might have
inaccurate information. For example, none of the computers, printers,
or routers in my basement area network are registered with any DNS
server. Since I can never remember which addresses
I've assigned to which systems, I wrote a simple
program that attempts to connect to all 254 possible local addresses
in turn to see which ones are active. (This only took me about 10
times as long as writing down all the addresses on a piece of paper.)getByAddress(byte[] address) really
doesn't do anything
getByAddress(String address)
doesn't do. In a few cases, it might be marginally
faster because it doesn't have to convert a string
to a byte array, but that's a trivial improvement.
getByAddress(String hostName,
byte[] address) does let you
create InetAddress objects that
don't match or even actively conflict with the
information in the local DNS. There might occasionally be a call for
this, but the use case is pretty obscure.
6.1.1.4 public static InetAddress getLocalHost( ) throws UnknownHostException
The InetAddress class contains one final means of
getting an InetAddress object. The static method
InetAddress.getLocalHost() returns the
InetAddress of the machine on which
it's running. Like InetAddress.getByName(
) and InetAddress.getAllByName( ), it
throws an UnknownHostException when it
can't find the address of the local machine (though
this really shouldn't happen). Its use is
straightforward:
InetAddress me = InetAddress.getLocalHost( );Example 6-4 prints the address of the machine
it's run on.
Example 6-4. Find the address of the local machine
import java.net.*;Here's the output; I ran the program on
public class MyAddress {
public static void main (String[] args) {
try {
InetAddress address = InetAddress.getLocalHost( );
System.out.println(address);
}
catch (UnknownHostException ex) {
System.out.println("Could not find this computer's address.");
}
}
}
titan.oit.unc.edu:
% java MyAddressWhether you see a fully qualified name like
titan.oit.unc.edu/152.2.22.14
titan.oit.unc.edu or a partial name like
titan depends on what the local DNS server
returns for hosts in the local domain. If you're not
connected to the Internet, and the system does not have a fixed IP
address or domain name, you'll probably see
localhost as the domain name and
127.0.0.1 as the IP
address.
6.1.2 Security Issues
Creating a new
InetAddress object from a hostname is considered a
potentially insecure operation because it requires a DNS lookup. An
untrusted applet under the control of the default security manager
will only be allowed to get the IP address of the host it came from
(its codebase) and possibly the local host.
Untrusted code is not allowed to create an
InetAddress object from any other hostname. This
is true whether the code uses the InetAddress.getByName(
) method, the InetAddress.getAllByName() method, the InetAddress.getLocalHost(
) method, or something else. Untrusted code can construct
an InetAddress object from the string form of the
IP address, though it will not perform DNS lookups for such
addresses.Untrusted code is not allowed to perform arbitrary DNS lookups for
third-party hosts because of the prohibition against making network
connections to hosts other than the codebase. Arbitrary DNS lookups
would open a covert channel by which a program could talk to
third-party hosts. For instance, suppose an applet downloaded from
www.bigisp.com wants to send the message
"macfaq.dialup.cloud9.net is
vulnerable" to crackersinc.com.
All it has to do is request DNS information for
macfaq.dialup.cloud9.net.is.vulnerable.crackersinc.com.
To resolve that hostname, the applet would contact the local DNS
server. The local DNS server would contact the DNS server at
crackersinc.com. Even though these hosts
don't exist, the cracker can inspect the DNS error
log for crackersinc.com to retrieve the message.
This scheme could be considerably more sophisticated with
compression, error correction, encryption, custom DNS servers that
email the messages to a fourth site, and more, but this version is
good enough for a proof of concept. Arbitrary DNS lookups are
prohibited because arbitrary DNS lookups leak information.Untrusted code is allowed to call InetAddress.getLocalHost(). However, this method returns a hostname of
localhost and an IP address of 127.0.0.1. This
is a special hostname and IP address called the loopback
address. No matter which machine you use this hostname or
IP address on, it always refers to the current machine. No specific
DNS resolution is necessary. The reason for prohibiting the applet
from finding out the true hostname and address is that the computer
on which the applet is running may be deliberately hidden behind a
firewall. In this case, an applet should not be a channel for
information the web server doesn't already have.
(Some older browsers, including Netscape 4.x, do allow a little more
information about the local host to leak out, including its IP
address, but only if no DNS lookup is required to get this
information.)Like all security checks, prohibitions against DNS resolutions can be
relaxed for trusted code. The specific
SecurityManager method used to test whether a host
can be resolved is checkConnect( ):
public void checkConnect(String hostname, int port)When the port argument is -1, this method checks
whether DNS may be invoked to resolve the specified
host. (If the port argument is
greater than -1, this method checks whether a connection to the named
host on the specified port is allowed.) The host
argument may be either a hostname like www.oreilly.com, a dotted quad IP address
like 208.201.239.37, or, in Java
1.4 and later, a hexadecimal IPv6 address like FEDC::DC:0:7076:10.You can grant an applet permission to resolve a host by using the
Policy Tool to add a java.net.SocketPermission
with the action connect and the target being the name of the host you
want to allow the applet to resolve. You can use the asterisk
wildcard (*) to allow all hosts in particular domains to be resolved.
For example, setting the target to *.oreilly.com
allows the applet to resolve the hosts www.oreilly.com, java.oreilly.com, perl.oreilly.com, and all others in the
oreilly.com domain. Although
you'll generally use a hostname to set permissions,
Java checks it against the actual IP addresses. In this example, that
also allows hosts in the ora.com domain to be
resolved because this is simply an alias for
oreilly.com with the same range of IP addresses.
To allow all hosts in all domains to be resolved, just set the target
to *. Figure 6-1 demonstrates.
Figure 6-1. Using the Policy Tool to grant DNS resolution permission to all applets

6.1.3 Getter Methods
The
InetAddress class contains three getter methods
that return the hostname as a string and the IP address as both a
string and a byte array:
public String getHostName( )There are no corresponding setHostName( ) and
public byte[] getAddress( )
public String getHostAddress( )
setAddress( ) methods, which means that packages
outside of java.net can't change
an InetAddress object's fields
behind its back. Therefore, Java can guarantee that the hostname and
the IP address match each other. This has the beneficial side effect
of making InetAdddress immutable and thus
thread-safe.
6.1.3.1 public String getHostName( )
The getHostName( ) method returns a
String that contains the name of the host with the
IP address represented by this InetAddress object.
If the machine in question doesn't have a hostname
or if the security manager prevents the name from being determined, a
dotted quad format of the numeric IP address is returned. For
example:
InetAddress machine = InetAddress.getLocalHost( );In some cases, you may only see a partially qualified name like
String localhost = machine.getHostName( );
titan instead of the full name like
titan.oit.unc.edu. The details depend on how the
local DNS behaves when resolving local hostnames.The getHostName( ) method is particularly useful
when you're starting with a dotted quad IP address
rather than the hostname. Example 6-5 converts the
dotted quad address 208.201.239.37 into a hostname by using
InetAddress.getByName( ) and then applying
getHostName( ) on the resulting object.
Example 6-5. Given the address, find the hostname
import java.net.*;Here's the result:
public class ReverseTest {
public static void main (String[] args) {
try {
InetAddress ia = InetAddress.getByName("208.201.239.37");
System.out.println(ia.getHostName( ));
}
catch (Exception ex) {
System.err.println(ex);
}
}
}
% java ReverseTest
www.oreillynet.com
6.1.3.2 public String getHostAddress( )
The getHostAddress() method returns a string containing the
dotted quad format of the IP address. Example 6-6
uses this method to print the IP address of the local machine in the
customary format.
Example 6-6. Find the IP address of the local machine
import java.net.*;Here's the result:
public class MyAddress {
public static void main(String[] args) {
try {
InetAddress me = InetAddress.getLocalHost( );
String dottedQuad = me.getHostAddress( );
System.out.println("My address is " + dottedQuad);
}
catch (UnknownHostException ex) {
System.out.println("I'm sorry. I don't know my own address.");
}
}
}
% java MyAddressOf course, the exact output depends on where the program is run.
My address is 152.2.22.14.
6.1.3.3 public byte[] getAddress( )
If you want to know the IP address of a machine (and you rarely do),
getAddress( ) returns an IP address as an array of
bytes in network byte order. The most significant byte (i.e., the
first byte in the address's dotted quad form) is the
first byte in the array, or element zeroremember, Java array
indices start with zero. To be ready for IPv6 addresses, try not to
assume anything about the length of this array. If you need to know
the length of the array, use the array's
length field:
InetAddress me = InetAddress.getLocalHost( );The bytes returned are unsigned, which poses a problem. Unlike C,
byte[] address = me.getAddress( ));
Java doesn't have an unsigned byte primitive data
type. Bytes with values higher than 127 are treated as negative
numbers. Therefore, if you want to do anything with the bytes
returned by getAddress( ), you need to promote the
bytes to ints and make appropriate adjustments.
Here's one way to do it:
int unsignedByte = signedByte < 0 ? signedByte + 256 : signedByte;Here, signedByte may be either positive or
negative. The conditional operator ? tests whether
signedByte is negative. If it is, 256 is added to
signedByte to make it positive. Otherwise,
it's left alone. signedByte is
automatically promoted to an int before the
addition is performed so wraparound is not a problem.One reason to look at the raw bytes of an IP address is to determine
the type of the address. Test the number of bytes in the array
returned by getAddress( ) to determine whether
you're dealing with an IPv4 or IPv6 address. Example 6-7 demonstrates.
Example 6-7. Print the IP address of the local machine
import java.net.*;
public class AddressTests {
public static int getVersion(InetAddress ia) {
byte[] address = ia.getAddress( );
if (address.length == 4) return 4;
else if (address.length == 16) return 6;
else return -1;
}
}
6.1.4 Address Types
Some IP addresses and some patterns of
addresses have special meanings. For instance, I've
already mentioned that 127.0.0.1 is the local loopback address. IPv4
addresses in the range 224.0.0.0 to 239.255.255.255 are multicast
addresses that send to several subscribed hosts at once. Java 1.4 and
later include 10 methods for testing whether an
InetAddress object meets any of these criteria:
public boolean isAnyLocalAddress( )
public boolean isLoopbackAddress( )
public boolean isLinkLocalAddress( )
public boolean isSiteLocalAddress( )
public boolean isMulticastAddress( )
public boolean isMCGlobal( )
public boolean isMCNodeLocal( )
public boolean isMCLinkLocal( )
public boolean isMCSiteLocal( )
public boolean isMCOrgLocal( )
6.1.4.1 public boolean isAnyLocalAddress( )
This method returns true if the address is a
wildcard address, false otherwise. A wildcard address
matches any address of the local system. This is important if the
system has multiple network interfaces, e.g. several Ethernet cards
or an Ethernet card and a wireless connection. This is normally
important only on servers and gateways. In IPv4, the wildcard address
is 0.0.0.0. In IPv6 this address is 0:0:0:0:0:0:0:0 (a.k.a ::).
6.1.4.2 public boolean isLoopbackAddress( )
This method returns true if the address is the
loopback address, false otherwise. The
loopback address connects to the same computer directly in the IP
layer without using any physical hardware. Thus, connecting to the
loopback address enables tests to bypass potentially buggy or
nonexistent Ethernet, PPP, and other drivers, helping to isolate
problems. Connecting to the loopback address is not the same as
connecting to the system's normal IP address from
the same system. In IPv4, this address is 127.0.0.1. In IPv6, this
address is 0:0:0:0:0:0:0:1 (a.k.a. ::1).
6.1.4.3 public boolean isLinkLocalAddress( )
This method returns true if the address is an
IPv6 link-local address, false
otherwise. This is an address used to help IPv6 networks
self-configure, much like DHCP on IPv4 networks but without
necessarily using a server. Routers do not forward these packets
beyond the local subnet. All link-local addresses begin with the
eight bytes FE80:0000.0000:0000. The next eight bytes are filled with
a local address, often copied from the Ethernet MAC address assigned
by the Ethernet card manufacturer.
6.1.4.4 public boolean isSiteLocalAddress( )
This method returns true if the address is an
IPv6 site-local address, false
otherwise. Site-local addresses are similar to link-local addresses
except that they may be forwarded by routers within a site or campus
but should not be forwarded beyond that site. Site-local addresses
begin with the eight bytes FEC0:0000.0000:0000. The next eight bytes
are filled with a local address, often copied from the Ethernet MAC
address assigned by the Ethernet card manufacturer.
6.1.4.5 public boolean isMulticastAddress( )
This method returns true if the address is a
multicast address, false otherwise.
Multicasting broadcasts content to all subscribed computers rather
than to one particular computer. In IPv4, multicast addresses all
fall in the range 224.0.0.0 to 239.255.255.255. In IPv6, they all
begin with byte FF. Multicasting will be discussed in Chapter 14.
6.1.4.6 public boolean isMCGlobal( )
This method returns true if the address is a
global multicast address, false
otherwise. A global multicast address may have subscribers around the
world. All multicast addresses begin with FF. In IPv6, global
multicast addresses begin with FF0E or FF1E depending on whether the
multicast address is a well known permanently assigned address or a
transient address. In IPv4, all multicast addresses have global
scope, at least as far as this method is concerned. As
you'll see in Chapter 14, IPv4
uses time-to-live (TTL) values to control scope rather than
addressing.
6.1.4.7 public boolean isMCOrgLocal( )
This method returns true if the address is an
organization-wide multicast
address, false otherwise. An organization-wide multicast address may
have subscribers within all the sites of a company or organization,
but not outside that organization. Organization multicast addresses
begin with FF08 or FF18, depending on whether the multicast address
is a well known permanently assigned address or a transient address.
6.1.4.8 public boolean isMCSiteLocal( )
This method returns true if the address is a
site-wide multicast address,
false otherwise. Packets addressed to a site-wide address will only
be transmitted within their local site. Organization multicast
addresses begin with FF05 or FF15, depending on whether the multicast
address is a well known permanently assigned address or a transient
address.
6.1.4.9 public boolean isMCLinkLocal( )
This method returns true if the address is a
subnet-wide multicast
address, false otherwise. Packets addressed to a link-local address
will only be transmitted within their own subnet. Link-local
multicast addresses begin with FF02 or FF12, depending on whether the
multicast address is a well known permanently assigned address or a
transient address.
6.1.4.10 public boolean isMCNodeLocal( )
This method returns true if the address is an
interface-local multicast
address, false otherwise. Packets addressed to an interface-local
address are not sent beyond the network interface from which they
originate, not even to a different network interface on the same
node. This is primarily useful for network debugging and testing.
Interface-local multicast addresses begin with the two bytes FF01 or
FF11, depending on whether the multicast address is a well known
permanently assigned address or a transient address.
|
of an address entered from the command line using these 10 methods.
Example 6-8. Testing the characteristics of an IP address (Java 1.4 only)
import java.net.*;Here's the output from an IPv4 and IPv6 address:
public class IPCharacteristics {
public static void main(String[] args) {
try {
InetAddress address = InetAddress.getByName(args[0]);
if (address.isAnyLocalAddress( )) {
System.out.println(address + " is a wildcard address.");
}
if (address.isLoopbackAddress( )) {
System.out.println(address + " is loopback address.");
}
if (address.isLinkLocalAddress( )) {
System.out.println(address + " is a link-local address.");
}
else if (address.isSiteLocalAddress( )) {
System.out.println(address + " is a site-local address.");
}
else {
System.out.println(address + " is a global address.");
}
if (address.isMulticastAddress( )) {
if (address.isMCGlobal( )) {
System.out.println(address + " is a global multicast address.");
}
else if (address.isMCOrgLocal( )) {
System.out.println(address
+ " is an organization wide multicast address.");
}
else if (address.isMCSiteLocal( )) {
System.out.println(address + " is a site wide multicast
address.");
}
else if (address.isMCLinkLocal( )) {
System.out.println(address + " is a subnet wide multicast
address.");
}
else if (address.isMCNodeLocal( )) {
System.out.println(address
+ " is an interface-local multicast address.");
}
else {
System.out.println(address + " is an unknown multicast
address type.");
}
}
else {
System.out.println(address + " is a unicast address.");
}
}
catch (UnknownHostException ex) {
System.err.println("Could not resolve " + args[0]);
}
}
}
$ java IPCharacteristics 127.0.0.1
/127.0.0.1 is loopback address.
/127.0.0.1 is a global address.
/127.0.0.1 is a unicast address.
$ java IPCharacteristics 192.168.254.32
/192.168.254.32 is a site-local address.
/192.168.254.32 is a unicast address.
$ java IPCharacteristics www.oreilly.com
www.oreilly.com/208.201.239.37 is a global address.
www.oreilly.com/208.201.239.37 is a unicast address.
$ java IPCharacteristics 224.0.2.1
/224.0.2.1 is a global address.
/224.0.2.1 is a global multicast address.
$ java IPCharacteristics FF01:0:0:0:0:0:0:1
/ff01:0:0:0:0:0:0:1 is a global address.
/ff01:0:0:0:0:0:0:1 is an interface-local multicast address.
$ java IPCharacteristics FF05:0:0:0:0:0:0:101
/ff05:0:0:0:0:0:0:101 is a global address.
/ff05:0:0:0:0:0:0:101 is a site wide multicast address.
$ java IPCharacteristics 0::1
/0:0:0:0:0:0:0:1 is loopback address.
/0:0:0:0:0:0:0:1 is a global address.
/0:0:0:0:0:0:0:1 is a unicast address.
6.1.5 Testing Reachability // Java 1.5
Java 1.5 adds two new methods to
the InetAddress class that enable applications to
test whether a particular node is reachable from the current host;
that is, whether a network connection can be made. Connections can be
blocked for many reasons, including firewalls, proxy servers,
misbehaving routers, and broken cables, or simply because the remote
host is not turned on when you try to connect. The
isReachable( ) methods allow you to test the
connection:
public boolean isReachable(int timeout) throws IOExceptionThese methods attempt to connect to the echo port on the remote host
public boolean isReachable(NetworkInterface interface, int ttl, int timeout)
throws IOException
site to find out if it's reachable. If the host
responds within timeout milliseconds, the methods
return true; otherwise, they return false. An
IOException will be thrown if
there's a network error. The second variant also
lets you specify the local network interface the connection is made
from and the "time-to-live" (the
maximum number of network hops the connection will attempt before
being discarded).In practice, these methods aren't very reliable
across the global Internet. Firewalls tend to get in the way of the
network protocols Java uses to figure out if a host is reachable or
not. However, you may be able to use these methods on the local
intranet.
6.1.6 Object Methods
Like
every other class,
java.net.InetAddress inherits from
java.lang.Object. Thus, it has access to all the
methods of that class. It overrides three methods to provide more
specialized behavior:
public boolean equals(Object o)
public int hashCode( )
public String toString( )
6.1.6.1 public boolean equals(Object o)
An object is equal to an
InetAddress object only if it is itself an
instance of the InetAddress class and it has the
same IP address. It does not need to have the same hostname. Thus, an
InetAddress object for
www.ibiblio.org is equal to an
InetAddress object for
www.cafeaulait.org since both names refer to the
same IP address. Example 6-9 creates
InetAddress objects for
www.ibiblio.org and
helios.metalab.unc.edu and then tells you
whether they're the same machine.
Example 6-9. Are www.ibiblio.org and helios.metalab.unc.edu the same?
import java.net.*;When you run this program, you discover:
public class IBiblioAliases {
public static void main (String args[]) {
try {
InetAddress ibiblio = InetAddress.getByName("www.ibiblio.org");
InetAddress helios = InetAddress.getByName("helios.metalab.unc.edu");
if (ibiblio.equals(helios)) {
System.out.println
("www.ibiblio.org is the same as helios.metalab.unc.edu");
}
else {
System.out.println
("www.ibiblio.org is not the same as helios.metalab.unc.edu");
}
}
catch (UnknownHostException ex) {
System.out.println("Host lookup failed.");
}
}
}
% java IBiblioAliases
www.ibiblio.org is the same as helios.metalab.unc.edu
6.1.6.2 public int hashCode( )
The hashCode( )
method returns an int that is needed when
InetAddress objects are used as keys in hash
tables. This is called by the various methods of
java.util.Hashtable. You will almost certainly not
need to call this method directly.Consistent with the equals( ) method, the
int that hashCode( ) returns is
calculated solely from the IP address. It does not take the hostname
into account. If two InetAddress objects have the
same address, then they have the same hash code, even if their
hostnames are different. Therefore, if you try to store two objects
in a Hashtable using equivalent
InetAddress objects as a key (for example, the
InetAddress objects for
helios.metalab.unc.edu and
www.ibiblio.org), the second will overwrite the
first. If this is a problem, use the String
returned by getHostName( ) as the key instead of
the InetAddress itself.
6.1.6.3 public String toString( )
Like all good classes, java.net.InetAddress has a
toString( )
method that returns a short text representation of the object. Example 6-1 through Example 6-4 all
implicitly called this method when passing
InetAddress objects to
System.out.println( ). As you saw, the string
produced by toString( ) has the form:
hostname/dotted quad addressNot all InetAddress objects have hostnames. If one
doesn't, the dotted quad address is substituted in
Java 1.3 and earlier. In Java 1.4, the hostname is set to the empty
string. This format isn't particularly useful, so
you'll probably never call toString() explicitly. If you do, the syntax is simple:
InetAddress thisComputer = InetAddress.getLocalHost( );
String address = thisComputer.toString( );