在互联网中通信需要借助 IP 地址来定位到主机,而 IP 地址由很多数字组成,对于人类来说记住某些组合数字很困难,于是,为了方便大家记住某地址而引入主机名和域名。
早期的网络中的机器数量很少,能很方便地通过 hosts 文件来完成主机名称和 IP 地址的映射,这种方式需要用户自己维护网络上所有主机的映射关系。后来互联网迅猛发展起来,hosts 文件方式已经无法胜任,于是引入域名系统(DNS)来解决主机名称和 IP 地址的映射。
局域网中常用来表示 IP 地址的名称更多称为主机名,而互联网上用来表示 IP 地址的名称更多称为域名。核心内容都相同,都是解决名称和 IP 地址间的映射。
Java 中提供了很多互联网主机名称和地址操作相关的接口,现在来看看 JDK 内部对域名解析相关功能的实现。其实,InetAddress 类内部存在一个 NameService 内部接口用于实现域名及IP的映射。
对于 JDK 主要使用了两种映射解析方案,一种是 hosts 文件机制,另外一种是操作系统自带的解析方案。
相关类
[Java]
纯文本查看
复制代码
1
2
3
|
--java.lang.Object
--java.net.InetAddress$HostsFileNameService
--java.net.InetAddress$PlatformNameService
|
JDK选择的方案
以上两种主机名称 IP 映射机制,JDK 是怎样选择的呢?其实就是根据 jdk.net.hosts.file系统属性来确定的,默认情况下使用基于操作系统的 PlatformNameService 方案,而如果配置了jdk.net.hosts.file系统属性则使用基于 hosts 文件的 HostsFileNameService 方案,比如可以在启动时配置参数 -Djdk.net.hosts.file=/etc/hosts。对应逻辑代码如下:
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
|
private
static
NameService createNameService() {
String hostsFileName =
GetPropertyAction.privilegedGetProperty(
"jdk.net.hosts.file"
);
NameService theNameService;
if
(hostsFileName !=
null
) {
theNameService =
new
HostsFileNameService(hostsFileName);
}
else
{
theNameService =
new
PlatformNameService();
}
return
theNameService;
}
|
接口定义
[Java]
纯文本查看
复制代码
1
2
3
4
5
6
7
|
private
interface
NameService {
InetAddress[] lookupAllHostAddr(String host)
throws
UnknownHostException;
String getHostByAddr(
byte
[] addr)
throws
UnknownHostException;
}
|
NameService 接口主要定义了两个方法,用于获取主机名称对应的 IP 地址和 IP 地址对应的主机名称。
HostsFileNameService 类
类定义如下:
[Java]
纯文本查看
复制代码
1
|
private
static
final
class
HostsFileNameService
implements
NameService
|
该类
|