java.net.InetAddress类是Java对IP地址(包括IPv4和IPv6)的高层表示,它包括一个主机名和一个IP地址。
创建InetAddress对象
InetAddress类没有公共构造函数,而是提供了一些静态工厂方法,可以连接到DNS服务器来解析主机名。
1.例如getByName(String host)方法:
InetAddress address = InetAddress.getByName("www.baidu.com");
如果DNS服务器找不到这个主机名,以上方法会抛出一个UnknownHostException,这是IOException的一个子类。
如果host参数是一个IP地址,则不会与DNS服务器交互,所创建InetAddress对象的主机名为null,只有显式地通过getHostName()才会完成主机名的DNS查找。
2.有时一个域名会映射到多个IP地址,如果要得到一个主机或域名的所有地址,可以调用getAllByName(String host)方法:
InetAddress[] addresses = InetAddress.getAllByName("www.baidu.com");
3.getLocalHost()方法会为运行这个代码的主机返回一个InetAddress对象:
InetAddress me = InetAddress.getLocalHost();
这个方法尝试连接DNS服务器来获取一个真正的主机名和IP地址,例如“LAPTOP-B8RFBDMB/192.168.1.101”,如果失败就会返回回送地址,即“localhost/127.0.0.1”。
4.如果知道一个IP地址,可以调用getByAddress(byte[] addr)或者getByAddress(String host, byte[] addr)方法,由这个地址创建一个InetAddress对象,而且不会与DNS服务器交互。
byte[] addr = {(byte) 192, (byte) 168, 1, 101};
InetAddress address = InetAddress.getByAddress(addr);
这两个方法不能保证这个主机一定存在,或者主机名能正确映射到IP地址。只有当作为addr参数传入的字节数组长度不合法时(既不是4字节也不是16字节)才会抛出UnknowHostException。
获取方法
InetAddress类包含四个获取方法,可以将主机名返回为字符串,将IP地址返回为字符串或者字节数组。
1.getHostName()方法返回InetAddress对象的主机名,如果InetAddress对象是通过主机名创建的则直接返回主机名,否则进行DNS查找后返回主机名,如果安全管理器阻止DNS查找则返回IP地址。
public String getHostName() {
return getHostName(true);
}
String getHostName(boolean check) {
if (holder().getHostName() == null) {
holder().hostName = InetAddress.getHostFromNameService(this, check);
}
return holder().getHostName();
}
2.getCanonicalHostName()方法与getHostName()方法类似,不同的是getHostName()方法在不知道主机名的时候才会进行DNS查找,而getCanonicalHostName()方法无论是否知道主机名都会直接进行DNS查找,如果安全管理器阻止DNS查找则返回IP地址。
public String getCanonicalHostName() {
if (canonicalHostName == null) {
canonicalHostName =
InetAddress.getHostFromNameService(this, true);
}
return canonicalHostName;
}
3.getHostAddress()方法将IP地址返回为字符串,具体由InetAddress类的子类Inet4Address和Inet6Address实现。
public String getHostAddress() {
return null;
}
4.getAddress()方法将IP地址以网络字节顺序返回为字节数组,IP地址的最高字节对应数组的第一个元素,由于IP地址的字节数采用无符号位而Java的字节类型是有符号位,大于127的字节数会被Java转换成负数形式,因此需要将字节数转换成int类型并作适当调整。
int segment = addr[i] < 0 ? addr[i] + 256 : addr[i];
getAddress()方法同样由InetAddress类的子类Inet4Address和Inet6Address实现。
public byte[] getAddress() {
return null;
}
测试可达性
InetAddress类有两个isReachable()方法,可以测试当前主机对一个指定节点是否能够建立网络连接。连接可能由于很多原因而阻塞,包括防火墙、代理服务器、行为失常的路由器和断开的线缆等,或者只是因为试图连接时远程主机没有开机。这些方法尝试使用ICMP echo请求查看指定节点是否可以连接。如果指定节点在timeout毫秒内响应,则方法返回true,否则返回false。如果出现网络错误则抛出IOException。
public boolean isReachable(int timeout) throws IOException {
return isReachable(null, 0 , timeout);
}
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);
}
第二个方法还指定了从哪个本地网络接口建立连接,以及连接被丢弃前尝试的最大网络跳数。
Object方法
public boolean equals(Object obj) {
return false;
}
public int hashCode() {
return -1;
}
public String toString() {
String hostName = holder().getHostName();
return ((hostName != null) ? hostName : "")
+ "/" + getHostAddress();
}
equals()方法和hashCode()方法由子类Inet4Address和Inet6Address实现。
对于toString()方法,不是所有InetAddress对象都有主机名,如果没有,Java1.3及以前版本使用IP地址替换,Java1.4及以后版本使用空字符串替换。