InetAddress代表一个IP地址。很多其他网络类都需要用到这个类。例如Socket、ServerSocket、URL等。
构造InetAddress
InetAddress这个类并没有公用的构造方法,我们不能通过构造方法来创建InetAddress对象,但是它提供了一些静态工厂方法,我们可以使用这些工厂方法来构建对象。这里我们来看一个常用的方法:
public static InetAddress getByName(String host)throws UnknownHostException {return InetAddress.getAllByName(host)[0];}
通过给定一个host来获取InetAddress对象,这个host可以是一个域名,例如www.baidu.com,也可以是一个ip,例如192.168.121.221。它是通过调用另外一个getAllByName方法实现的,我们先不去看这个方法,来写几个例子:
public static void main(String[] args) throws IOException {InetAddress inetAddress = InetAddress.getByName("www.baidu.com");System.out.println(inetAddress.getHostAddress());InetAddress localHost = InetAddress.getLocalHost();System.out.println(localHost.getHostName());System.out.println(localHost.getHostAddress());}
第一个是获取www.baidu.com这个域名的地址,注意一个域名可能对应多个主机也就是多个ip地址,这里获取的只是这些地址中的一个。getLocalHost是获取本机的地址,我们看输出:
110.242.68.4cuihualongdeMacBook-Pro.local192.168.20.89
也就是www.baidu.com的机器ip是110.242.68.4,我机器的ip是192.168.20.89,我机器的主机名是cuihualongdeMacBook-Pro.local。inetAddress的getHostName返回的是主机名,getHostAddress返回的是机器ip。
因为一个域名可能对应多个ip,所以正常情况下对于一个host,应该返回的是一个InetAddress的数组,这就是上面我们看到的getAllByName方法的功能,getByName也是获取的getAllByName返回的数组的第一个。我们来用一下getAllByName这个方法:
public static void main(String[] args) throws IOException {InetAddress[] allByName = InetAddress.getAllByName("www.baidu.com");for (InetAddress address : allByName) {System.out.println(address.getHostAddress());}}
输出:
110.242.68.3110.242.68.4
所以www.baidu.com应该是有两台机器。
然后我们来看geAllByName的逻辑:
public static InetAddress[] getAllByName(String host)throws UnknownHostException {return getAllByName(host, null);}
它调用的是getAllByName(),这里的逻辑有点多,就不再解释了。
可达性判断
InetAddress还提供了方法来判断这个地址的可达性:
public boolean isReachable(int timeout) throws IOException {return isReachable(null, 0 , timeout);}
它调用的是另外一个isReacheable方法:
public boolean isReachable(NetworkInterface netif, int ttl,int timeout) throws IOException {if (ttl < 0)throw new IllegalArgumentException("ttl can't be negative");if (timeout < 0)throw new IllegalArgumentException("timeout can't be negative");return impl.isReachable(this, timeout, netif, ttl);}
我们不去看代码逻辑,从注释看一下它是怎样判断可达性的:
Test whether that address is reachable. Best effort is made by the* implementation to try to reach the host, but firewalls and server* configuration may block requests resulting in a unreachable status* while some specific ports may be accessible.* A typical implementation will use ICMP ECHO REQUESTs if the* privilege can be obtained, otherwise it will try to establish* a TCP connection on port 7 (Echo) of the destination host.
如果有权限的话,它会使用ICMP ECHO REQUEST来判断可达性,否则会尝试建立一个到目的主机的7端口号的TCP连接。
