20

我们的一个 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?

4

1 回答 1

23

我怀疑这与其说是 Java 编程问题,不如说是 OS 网络堆栈/OS 网络配置问题:

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。

这是一篇关于互操作性的好文章:

您知道如何为您的 Java 应用程序“关闭”IPV6:-Djava.net.preferIPv4Stack=true

您还可以像这样强制您的服务器使用 IPV6:echo 0 > /proc/sys/net/ipv6/bindv6only

这可以说是你最好的来源:

您绝对应该能够完成您想要的(至少在 Java 编程级别),除非您受到外部网络问题的限制:

Nodes)      V4 Only  V4/V6  V6 Only
            -------  -----  -------
V4 Only     x        x   
V4/V6       x        x      x
V6 Only              x      x

PS:

这是另一个很好的链接,它解释了套接字级别发生的事情。它不是 Java(它是 C),但示例原则完全适用:

于 2012-04-30T04:39:26.177 回答