Java:JDK中IPv4和IPv6处理及域名缓存介绍

以下以JDK8为例说明对IPv4和IPv6是如何处理的。

一、常用代码

一般情况下,使用如下代码可以获取到域名/主机名对应的多个IP,其中部分是IPv4的,部分是IPv6的:

try {
	InetAddress[] addrs = InetAddress.getAllByName(host);

	for (InetAddress addr : addrs) {
		System.out.println(addr);
	}
} catch (UnknownHostException e) {
	e.printStackTrace();
}

TEST-NOTEBOOK/172.16.109.99
TEST-NOTEBOOK/25.38.108.104
TEST-NOTEBOOK/fe80:0:0:0:cc19:d6ad:fa78:db29%14
TEST-NOTEBOOK/fe80:0:0:0:81e:a44d:98e5:62cf%8

 如果添加了JVM参数-Djava.net.preferIPv4Stack=true,则执行结果为:

TEST-NOTEBOOK/172.16.109.99
TEST-NOTEBOOK/25.38.108.104

设置java.net.preferIPv4Stack=false与不设置java.net.preferIPv4Stack效果一样

二、执行过程分析

下面一起来分析一下整个执行过程:

1.InetAddress.getAllByName(..)内部实际调用的是红框中的方法

 2.上述方法中实际获取IP的方法如下:

 3.上述方法实际调用的方法定义如下:

 4.impl是在类的static方法中初始化的:

 5.InetAddressImplFactory的代码如下

可以看出impl最终采用Inet6AddressImpl还是Inet4AddressImpl,实际是根据native方法isIPv6Supported()决定的。另外Inet6AddressImpl支持IPv6和IPv4双栈,Inet4AddressImpl只支持IPv栈。

6.从JDK源码InetAddressImplFactory.c中可以找到实际调用的代码:

 从中可看到实际是调用方法:ipv6_available()

7.从JDK源码net_util.c中可以找到ipv6_available()的定义:

 从中可以看到ipv6_available()的返回值是由常量IPv6_available决定的,常量IPv6_available的值 是由IPv6_supported() 和 preferIPv4Stack决定的,

若配置JVM参数-Djava.net.preferIPv4Stack=false,则IPv6_available=0

若JDK所在系统不支持IPv6,则IPv6_available=0

8.判断系统是否支持IPv6的代码在net_util_md.c中

可以看到是通过尝试创建IPv6的socket来判断系统是否支持IPv6的

三、其它问题说明

1.JVM参数java.net.preferIPv6Addresses的用途

java.net.preferIPv6Addresses也是在java.net.InetAddress中定义的:

 会在java.net.Inet6AddressImpl中使用到:

 主要是用来生成IPv6格式的通配符地址和回路地址

2.域名缓存时长配置方式

(1)JDK中提供机制对找得到IP地址的域名和找不到IP地址的域名分别缓存,代码在java.net.Inet6AddressImpl中:

(2)这两种缓存的默认过期时长不同,代码在sun.net.InetAddressCachePolicy中:

a、找得到IP地址的域名的缓存:30s

b、找不到IP地址的域名的缓存:10s

 可以通过如下代码分别获取到过期时长:

sun.net.InetAddressCachePolicy.get();
sun.net.InetAddressCachePolicy.getNegative();

 可以通过如下JVM参数进行修改

a、找得到IP地址的域名的缓存

networkaddress.cache.ttl
sun.net.inetaddr.ttl

b、找不到IP地址的域名的缓存

networkaddress.cache.negative.ttl
sun.net.inetaddr.negative.ttl

参考源码:

java.net.InetAddress
java.net.Inet6Address
java.net.Inet4Address
sun.net.InetAddressCachePolicy
net_util.c
net_util_md.c
InetAddressImplFactory.c

参考文档

Networking Properties

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值