gpt4 book ai didi

java - 为什么两个 Java 进程可以绑定(bind)到 macOS 中的同一个套接字?

转载 作者:行者123 更新时间:2023-12-05 09:28:42 24 4
gpt4 key购买 nike

我有一些生成套接字绑定(bind)的 Java 代码。很难提供一个最小的示例,因为它是 Web 框架的一部分,但它在某些时候有效地执行了此检查。

  private static boolean portInUse(int port) {
// try to bind to this port, if it succeeds the port is not in use
try (ServerSocket socket = new ServerSocket(port)) {
socket.setReuseAddress(true);
return false;
} catch (IOException e) {
return true;
}
}

我可以看到,如果我使用相同的端口运行两个不同的 Java 进程,它们都会落入第一个条件并返回 false,因此它们都能够绑定(bind)到相同的端口。我已经通读了 some related socket questions and explanations like this one ,但他们似乎使我指定的选项听起来不可能。查看 setReuseAddress 的实现,它似乎只在套接字上设置了 SO_REUSEADDR

我可以看到一个进程在调试器中以类似 ServerSocket[addr=0.0.0.0/0.0.0.0,localport=56674] 的套接字结束。如果我运行类似 sudo lsof -n -i | 的东西grep -e LISTEN -e 已建立 | grep 56674 我可以看到两个进程绑定(bind)到同一个端口:

java      68863    natdempk 1256u  IPv4 0xbbac93fff9a6e677      0t0  TCP *:56674 (LISTEN)
java 68998 natdempk 985u IPv6 0xbbac93fff2f84daf 0t0 TCP *:56674 (LISTEN)

我还可以看到 gRPC 和 Node 等其他一些项目在问题跟踪器中提到了在他们的服务器上观察到的这种行为,但他们从未解释为什么这是可能的。 不同的进程如何绑定(bind)到 macOS 上的同一个套接字?

如果有帮助的话,我正在运行 macOS 11.6.3 (20G415)。如果有人有任何我应该在此处添加的内容,也很乐意提供更多调试信息。

最佳答案

它们没有绑定(bind)到同一个端口。一种是绑定(bind)到 IPv6 之上的 TCP,另一种是绑定(bind)到 IPv4 之上的 TCP。

稍微扩展一下 Java 细节:Java 中的 new ServerSocket(port) 使用 InetAddress.anyLocalAddress() 因为没有 InetAddress InetAddress.anyLocalAddress() 可以返回 IPv4 或 IPv6 地址,这意味着尽管传入了相同的端口,但不能保证绑定(bind)到 JVM 的值相同。

关于java - 为什么两个 Java 进程可以绑定(bind)到 macOS 中的同一个套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71148158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com