强制 ServerSocket 使用 IPv4

Force ServerSocket to use IPv4

我无法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,这是我想要的,但我只能通过发送特定的虚拟机选项来实现这个解决方案。

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

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

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