如何在 Java 上同时支持 IPv4 和 IPv6
Posted
技术标签:
【中文标题】如何在 Java 上同时支持 IPv4 和 IPv6【英文标题】:How to support both IPv4 & IPv6 on Java 【发布时间】:2012-05-09 20:16:50 【问题描述】:我们的一个 Java 程序在启动时只监听 IPv6 (8080)
例如
# netstat -ntpl
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::8080 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
问题是它无法从外部访问(本地主机除外),为了解决这个问题,我手动添加了这个
-Djava.net.preferIPv4Stack=true
但这使得该程序仅适用于 IPv4 网络。
是否可以像上面的 sshd 一样,同时支持 IPv4 和 IPv6?
【问题讨论】:
【参考方案1】:我怀疑这与其说是 Java 编程问题,不如说是操作系统网络堆栈/操作系统网络配置问题:
http://coding.derkeiler.com/Archive/Java/comp.lang.java.help/2009-09/msg00087.html
在某些操作系统上,一个本地 TCP 套接字可以监听两个操作系统上的端口 IPv4 和 IPv6 同时进行。它能够接受来自 远程 IPv4 和远程 IPv6 客户端。在其他操作系统上(例如 WinXP) 操作系统本机套接字不能这样做,但只能接受来自 IPv4 或 IPv6,而不是两者。在那些操作系统上,有必要有两个听 套接字,以便能够接受来自远程 IPv4 的连接 和 IPv6 客户端,一个用于侦听 IPv4 连接的套接字,一个用于侦听 IPv6。
Windows 7 和 Windows Server 2008 可以很好地处理双堆栈; Windows XP 没那么多:)
您似乎使用的是 Linux - 大多数现代 Linux 桌面和服务器也可以毫无问题地处理双 ipv4 ipv6。
这是一篇关于互操作性的好文章:
http://ntrg.cs.tcd.ie/undergrad/4ba2.02/ipv6/interop.html您知道如何为您的 Java 应用程序“关闭”IPV6:-Djava.net.preferIPv4Stack=true
您也可以像这样强制您的服务器使用 IPV6:echo 0 > /proc/sys/net/ipv6/bindv6only
这可以说是你最好的来源:
http://docs.oracle.com/javase/6/docs/technotes/guides/net/ipv6_guide/index.html你应该绝对能够完成你想要的(至少在 Java 编程级别),除非你受到外部网络问题的限制:
Nodes) V4 Only V4/V6 V6 Only
------- ----- -------
V4 Only x x
V4/V6 x x x
V6 Only x x
PS:
这是另一个很好的链接,它解释了套接字级别发生的事情。它不是 Java(它是 C),但正是应用示例原则:
Accept connections from both IPv6 and IPv4 clients【讨论】:
以上是关于如何在 Java 上同时支持 IPv4 和 IPv6的主要内容,如果未能解决你的问题,请参考以下文章