Java IPv6相关属性preferIPv4Stack、preferIPv6Addresses介绍

栏目: 服务器 · 发布时间: 7年前

内容简介:目前被广泛使用的IPv4,它的最大问题是网络地址资源有限。IPv4仅有32二进制位,满打满算也仅有不到43亿个IP地址,已经完全不能满足目前需求。IPv6有128二进制位,地址数量非常庞大。目前主流操作系统早已支持IPv6,Google、Facebook和Yahoo等网站也早已支持IPv6。2017年底中共中央办公厅、国务院办公厅印发在Java中对IPv6的支持是透明的且自动化的,无需移植,也无需重新编译源码。相对于其他语言而言(例如C++),Java很好封装了IPv4和IPv6两种版本的不同,Java一般

IPv6背景介绍

目前被广泛使用的IPv4,它的最大问题是网络地址资源有限。IPv4仅有32二进制位,满打满算也仅有不到43亿个IP地址,已经完全不能满足目前需求。IPv6有128二进制位,地址数量非常庞大。目前主流操作系统早已支持IPv6,Google、Facebook和Yahoo等网站也早已支持IPv6。2017年底中共中央办公厅、国务院办公厅印发 《推进互联网协议第六版(IPv6)规模部署行动计划》 ,推动国内IPv6的支持。目前已有大量国内网站和APP已经支持IPv6。未来数年将是IPv4到IPv6的过渡时期,IPv6和IPv4会并存,IPv6使用率也会逐渐提高。

Java对IPv6的支持

Networking IPv6 User Guide 文档中,介绍了 Java 对IPv6的支持情况:

IPv6 in Java is transparent and automatic. Porting is not necessary; there is no need to recompile source files.

Java中对IPv6的支持是透明的且自动化的,无需移植,也无需重新编译源码。相对于其他语言而言(例如C++),Java很好封装了IPv4和IPv6两种版本的不同,Java一般不需要在编写代码时关注IPv6如何支持,一个原本运行在IPv4环境的代码放到支持IPv6环境中一般也可以直接使用。

Java IPv6相关系统属性

由于Java封装了IPv4和IPv6的差异,在代码层面上不需要关注同时也无法设置使用IPv4还是IPv6,Java提供了 java.net.preferIPv4Stackjava.net.preferIPv6Addresses 两个系统属性,用于设置协议栈和地址族的选择。

这两个系统参数既可以在Java代码中设置:

System.setProperty("java.net.preferIPv4Stack", "true");

也可以在启动时通过JVM参数设置:

-Djava.net.preferIPv4Stack=true

java.net.preferIPv4Stack(默认值false)

官方文档解释:

If IPv6 is available on the operating system, the underlying native socket will be an IPv6 socket. This allows Java applications to connect to, and accept connections from, both IPv4 and IPv6 hosts.

java.net.preferIPv4Stack 为默认值false时,在支持IPv6的双栈系统上,使用Java的Socket会默认通过底层native方法创建一个IPv6 Socket,这个IPv6 Socket可以同时支持和IPv4或IPv6主机通信。如果设置为true,Java程序将无法使用IPv6进行网络通信,也就是仅支持IPv4。

例如,当TCP客户端 java.net.preferIPv4Stack 设置为true时,如果想创建一个host为IPv6的Socket,会抛出异常 java.net.SocketException: Protocol family unavailable ,设置为false时则程序可以正常运行:

System.setProperty("java.net.preferIPv4Stack", "true");
Socket socket = new Socket("::1", 80); // 访问IPv6地址::1(相当于IPv4的127.0.0.1)的80端口会抛出异常

当TCP服务器 java.net.preferIPv4Stack 设置为true时,通过IPv6访问就会访问不通。

在正常情况下,Tomcat或者Jetty等Java服务器启动后,可以使用浏览器通过IPv4地址 http://127.0.0.1:8080 或IPv6地址 http://[::1]:8080 两种方式访问,此时通过 lsof -i:8080 命令可以看到对应进程的Type为IPv6:

Java IPv6相关属性preferIPv4Stack、preferIPv6Addresses介绍

如果加上JVM参数 -Djava.net.preferIPv4Stack=true 启动,此时通过 lsof -i:8080 命令可以看到对应进程的Type为IPv4:

Java IPv6相关属性preferIPv4Stack、preferIPv6Addresses介绍

此时通过IPv6地址 http://[::1]:8080 将无法访问,仅可通过IPv4地址 http://127.0.0.1:8080 访问。

java.net.preferIPv6Addresses(默认值false)

官方文档解释:

By default, IPv4 addresses are preferred over IPv6 addresses, for example, when querying the name service (for instance, DNS service), IPv4 addresses would be returned ahead of IPv6 addresses. 

java.net.preferIPv6Addresses 为默认值false时,IPv4地址会优先使用,例如在DNS通过域名查询IP地址时,会优先使用IPv4地址,反之设为true,则会优先使用IPv6地址。

Google目前支持IPv4和IPv6,可以 host 命令查看域名 www.google.com DNS解析的IPv4和IPv6地址:

host www.google.com
> www.google.com has address 66.220.146.94
> www.google.com has IPv6 address 2404:6800:4008:803::2004

默认情况下会优先使用IPv4地址:

System.out.println(InetAddress.getByName("www.google.com"));

输出:

www.google.com/66.220.146.94

java.net.preferIPv6Addresses 设置为true时会优先使用IPv6地址:

System.setProperty("java.net.preferIPv6Addresses", "true");
System.out.println(InetAddress.getByName("www.google.com"));

输出:

www.google.com/2404:6800:4008:803:0:0:0:2004

另外,通过 InetAddress.getLocalHost() 方法返回本机IP地址,最终返回的是IPv4还是IPv6地址,也会由 java.net.preferIPv6Addresses 的值来决定。

参考资料


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网络营销实战密码

网络营销实战密码

昝辉Zac / 电子工业出版社 / 2009.1 / 56.00元

本书是作者几年来网络营销实战的总结,与其他网络营销书籍最大不同之处是:只专注于实战,不谈理论。本书分三部分详细介绍了网络营销实用策略和技巧,并分析了大量实战案例。第一部分介绍市场与产品研究,包括用户、市场和竞争对手的调查;产品、目标市场的确定;价格策略;赢利模式等。第二部分讨论以网络营销为导向的网站设计,包括怎样在网站上卖东西、提高转化率,以及网站目标设定等。第三部分研究怎样给网站带来流量,详细讨......一起来看看 《网络营销实战密码》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具