Tengo un código Java que está generando un enlace de socket. Es difícil proporcionar un ejemplo mínimo, ya que esto es parte de un marco web, pero efectivamente realiza esta verificación en algún momento.
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; } } Puedo ver que si ejecuto dos procesos Java distintos con el mismo puerto, ambos caen en el primer condicional y devuelven false , por lo que ambos pueden vincularse al mismo puerto. He leído algunas preguntas relacionadas con el socket y explicaciones como esta , pero parecen hacer que parezca que esto no debería ser posible con las opciones que he especificado. Al observar la implementación de setReuseAddress , solo parece configurar SO_REUSEADDR en el socket.
Puedo ver que un proceso termina con un socket como ServerSocket[addr=0.0.0.0/0.0.0.0,localport=56674] en un depurador. Si ejecuto algo como sudo lsof -n -i | grep -e LISTEN -e ESTABLISHED | grep 56674 Puedo ver dos procesos vinculados al mismo puerto:
java 68863 natdempk 1256u IPv4 0xbbac93fff9a6e677 0t0 TCP *:56674 (LISTEN) java 68998 natdempk 985u IPv6 0xbbac93fff2f84daf 0t0 TCP *:56674 (LISTEN)También puedo ver algunos otros proyectos como gRPC y Node mencionan este comportamiento que se observa con sus servidores en los rastreadores de problemas, pero nunca explican por qué esto es posible. ¿Cómo pueden vincularse distintos procesos al mismo socket en macOS?
Estoy ejecutando macOS 11.6.3 (20G415) si eso es útil. Feliz de proporcionar más información de depuración también si alguien tiene algo que deba agregar aquí.
No están vinculados al mismo puerto. Uno se vincula a TCP sobre IPv6, el otro se vincula a TCP sobre IPv4.
Para ampliar un poco los detalles de Java: el new ServerSocket(port) en Java usa InetAddress.anyLocalAddress() porque no se pasó InetAddress . InetAddress.anyLocalAddress() puede devolver una dirección IPv4 o IPv6, lo que significa que esto no está garantizado ser el mismo valor para vincular a través de JVM a pesar de que se pasa el mismo puerto.