如何同时支持 IPv4 &Java 上的 IPv6
我们的一个 Java 程序在启动时只监听 IPv6 (8080)
One of our Java program when started, it only listen on 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 -
问题是它无法从外部访问(本地主机除外),为了解决这个问题,我手动添加了这个
The problem is it is not accessible from outside (except localhost), to solve this, I have this manually add
-Djava.net.preferIPv4Stack=true
但这使得该程序仅适用于 IPv4 网络.
But this make the program is only for IPv4 network.
是否可以像上面的 sshd 一样,同时支持 IPv4 和 IPv6?
Is it possible to do something like the sshd as above, both support IPv4 and IPv6?
推荐答案
我怀疑这与其说是 Java 编程问题,不如说是操作系统网络堆栈/操作系统网络配置问题:
I suspect it's less a Java programming issue than an OS networking stack/OS network configuration issue:
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.
On some OSes, a single native TCP socket can listen to a port on both IPv4 and IPv6 simultaneously. It is able to accept connections from remote IPv4 and from remote IPv6 clients. On other OSes (such as WinXP) an OS native socket CANNOT do that, but can only accept from IPv4 or IPv6, not both. On those OSes, it is necessary to have two listen sockets in order to be able to accept connections from both remote IPv4 and IPv6 clients, one socket to listen for IPv4 connections and one for IPv6.
Windows 7 和 Windows Server 2008 可以很好地处理双堆栈;Windows XP 没那么多:)
Windows 7 and Windows Server 2008 handle dual stacks just fine; Windows XP not so much :)
您似乎使用的是 Linux - 大多数现代 Linux 桌面和服务器也可以毫无问题地处理双 ipv4 ipv6.
You seem to be on Linux - most modern Linux desktops and servers also handle dual ipv4 ipv6 with no problem.
这是一篇关于互操作性的好文章:
Here's a good article on interoperability:
- http://ntrg.cs.tcd.ie/undergrad/4ba2.02/ipv6/interop.html
您知道如何为您的 Java 应用程序关闭"IPV6:-Djava.net.preferIPv4Stack=true
You know how you can "turn off" IPV6 for your Java application: -Djava.net.preferIPv4Stack=true
您也可以像这样强制您的服务器使用 IPV6:echo 0 >/proc/sys/net/ipv6/bindv6only
You can also force your server to use IPV6 like this: echo 0 > /proc/sys/net/ipv6/bindv6only
这可以说是你最好的来源:
This is arguably your best source:
- http://docs.oracle.com/javase/6/docs/technotes/guides/net/ipv6_guide/index.html
你应该绝对能够完成你想要的(至少在 Java 编程级别),除非你受到外部网络问题的限制:
You should absolutely be able to accomplish what you want (at least at the Java programming level), unless you're limited by external network issues:
Nodes) V4 Only V4/V6 V6 Only
------- ----- -------
V4 Only x x
V4/V6 x x x
V6 Only x x
PS:
这是另一个很好的链接,它解释了套接字级别发生的事情.它不是 Java(它是 C),但正是应用示例原则:
Here's one more good link, which explains what's happening at the socket level. It's not Java (it's C), but exactly the sample principles apply:
- 接受来自 IPv6 和 IPv4 客户端的连接一个>
相关文章