Java:JDK对IPv4和IPv6处理介绍

news/2024/12/2 14:53:07/

以下以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


http://www.ppmy.cn/news/49479.html

相关文章

2023年全国最新二级建造师精选真题及答案60

百分百题库提供二级建造师考试试题、二建考试预测题、二级建造师考试真题、二建证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 51.关于债的基本法律关系的说法,正确的是()。 A.债是不特…

6 计时器(六)

6.7 TMI编码器接口 Encoder Interface 编码器接口 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度 每个高级定时器和通…

Linux下C/C++实现(网络流量分析-NTA)

网络流量分析(NTA - Network Traffic Analysis) 就是捕捉网络中流动的数据包,并通过查看包内部数据以及进行相关的协议、流量、分析、统计等,协助发现网络运行过程中出现的问题。通过监控和分析网络环境中的流量,来判断流量是用在…

Linux下彻底解决mysql中文乱码

文章目录 Linux下彻底解决mysql中文乱码1.修改 MySQL 服务器的字符集为 UTF-8,可以在 my.cnf 配置文件中添加以下内容:2.使用时修改 MySQL 数据库和表的字符集为 UTF-8,可以使用以下命令:3.在建立数据库连接时,使用 UT…

【LeetCode】144.二叉树的前序遍历

1.问题 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。示例 1: 输入:root [1,null,2,3] 输出:[1,2,3] 示例 2: 输入:root [] 输出:[] 示例 3: 输入:root [1]…

如何智能改写文案内容-如何用ai改字

伪原创在线文章生成器 在当今数字时代,营销推广已成为各行各业的必备工具,其中之一便是内容营销。作为内容营销的一部分,文章撰写是非常关键的环节。为了满足市场需求,越来越多的在线文章生成器涌现出来,其中最受欢迎…

【C++】二叉搜索树(概念、实现、应用以及OJ题详解)

前言: 此前我们在C语言实现数据结构的时候学习过二叉树,但是那个时候我们没有深入学习二叉搜索树。本章重提二叉树并详解二叉搜索树有下面两个原因: 1、为我们下一章学习set和map做准备;2、详解我们进阶一点的二叉树的面试OJ题&a…

高新技术企业申报有哪些常见问题

高新技术企业 高新技术企业是指在中国(不包括香港、澳门、台湾)注册一年以上的居民企业,在国家重点支持的高新技术领域不断开展研发和技术成果转化,形成企业核心自主知识产权,并在此基础上开展经营活动。 高新技术企…