我无法设法使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)


您会注意到,即使我在创建ServerSocket时指定了“ 0.0.0.0” IPv4地址,我们监听端口11000的地址也是一个IPv6地址。

另一方面,如果在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堆栈版本?

最佳答案

tcp46套接字类型可以看到,IPv6套接字还可以侦听传入的IPv4连接。没有什么不妥。 IPv6的增长速度非常快,并且确保您的软件可以同时使用IPv4和IPv6是一种很好的做法,它将防止将来(和今天)发生许多问题。

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

10-06 13:42
查看更多