【问题标题】:Force ServerSocket to use IPv4强制 ServerSocket 使用 IPv4
【发布时间】:2019-05-02 18:05:57
【问题描述】:

我无法让ServerSocket 使用 IPv4 而不是 IPv6,这似乎是我系统上的默认行为。

跑步 new ServerSocket(11000, queueLimit, InetAddress.getByName("0.0.0.0") 会导致

➜  ~ netstat -an | grep 11000
tcp46      0      0  *.11000                *.*                    LISTEN

➜  ~ lsof -i :11000
COMMAND PID  USER   FD   TYPE DEVICE             SIZE/OFF NODE NAME
java    2845 myuser 383u IPv6 0x5ba3bfaea6c7372d 0t0      TCP *:irisa (LISTEN)

如您所见,我们监听端口 11000 的地址是 IPv6 地址,即使我在创建 ServerSocket 时指定了“0.0.0.0” IPv4 地址。

另一方面,如果我在 vm 选项上指定-Djava.net.preferIPv4Stack=true,我会得到以下场景。

➜  ~ netstat -an | grep 11000
tcp4       0      0  *.11000                *.*                    LISTEN

➜  ~ lsof -i :11000
COMMAND PID  USER   FD   TYPE DEVICE             SIZE/OFF NODE NAME
java    3628 myuser 384u IPv4 0x5ba3bfaeaafaa08d 0t0      TCP *:irisa (LISTEN)

您现在可以注意到,我现在可以正确侦听 IPv4 地址上的端口 11000,这正是我想要的,但我只能通过发送特定的 vm 选项来达到此解决方案。

在打开ServerSocket 时,我如何可靠地决定我可以收听哪个版本的 IP 堆栈?

【问题讨论】:

    标签: java ipv6 serversocket ipv4 netstat


    【解决方案1】:

    IPv6 套接字还可以侦听传入的 IPv4 连接,正如您从 tcp46 套接字类型中看到的那样。没有什么不妥。 IPv6 的发展速度非常快,确保您的软件可以同时使用 IPv4 和 IPv6 是一种很好的做法,可以防止未来(以及现在)出现许多问题。

    强烈建议不要强制套接字仅侦听 IPv4。

    【讨论】:

    • 可能是这样,但它肯定有一些有效的用例 - 例如与旧硬件通信,或处理没有校验和的 UDP 流量,因为 IPV6 需要对 UDP 流量进行校验和......
    • @user2366842 为什么同时监听 IPv4 和 IPv6 对传统硬件(可能使用 IPv4)来说是个问题?
    • 感谢您的回复。我有一个后续问题:如果一个应用程序正在侦听机器 IPv6 接口上的端口 11000,而另一个应用程序正在侦听同一端口 11000 但在 IPv4 接口上,如果连接到端口,将联系这两个应用程序中的哪一个IPv4接口上执行11000?
    • Ivano:您给出的示例表明应用程序正在侦听 IPv4 和 IPv6。您不能让其他应用程序在同一端口上侦听。
    • 您好@SanderSteffann,再次感谢您的评论。也许我遗漏了一些东西,但是如果我在0.0.0.0 上启动一个python SimpleHttpServer 然后在同一个端口上创建一个new ServerSocket,我会得到以下信息:~ netstat -an | grep 11000tcp46 0 0 *.11000 *.* LISTENtcp4 0 0 *.11000 *.* LISTEN
    猜你喜欢
    • 2016-01-07
    • 2012-01-18
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多