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.4
cuihualongdeMacBook-Pro.local
192.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.3
110.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连接。