¿Cuál es la semántica de obtener un EADDRINUSE cuando no hay ningún conector de escucha vinculado, pero las conexiones están abiertas?

¿Cuál es la semántica de obtener un EADDRINUSE cuando no hay ningún conector de escucha vinculado, pero las conexiones están abiertas?

Considere un proceso principal que completa un socket/bind/accepty bifurcará a los niños con ese socket abierto para que se comuniquen, mientras el padre continúa aceptando conexiones. Luego, ese proceso principal se elimina.

Otro proceso ahora intenta vincularse a la misma dirección a la que estaba vinculado el proceso principal, en el mismo puerto, pero recibe un error EADDRINUSE.

Sin embargo, cuando completa este proceso con sshd, parecesshd escapaz de volver a vincularse al puerto que se cerró, mientras que durante la ventana de reinicio (donde el proceso principal sshd no se está ejecutando), un programa diferente (que se ejecuta como un usuario diferente) simplemente obtiene EADDRINUSE.

¿Cuál es la semántica detrás de esto? ¿Por qué se puede sshdvolver a vincular, pero el proceso de otro usuario no?

Además, puedo confirmar que la netstat -a | grep PORTsalida durante el tiempo en que solo se ejecuta el proceso secundario (cuando el otro proceso no puede bind), la única conexión es la ESTABLISHEDúnica, ninguna en LISTENestado.

Respuesta1

Si bien no entiendo toda la semántica (estoy buscando en el lugar equivocado o falta la documentación), creo que durante un cierto período de tiempo después de cerrar una conexión (tal vez establecida por SO_LINGER), ningún proceso puede Abra un nuevo enchufe con los mismos detalles a menos que se hayan SO_REUSEADDRconfigurado.

Esto es para evitar que alguien se vuelva a conectar un segundo después de cerrar una conexión y que el proceso tenga que lidiar con paquetes que estaban destinados al proceso anterior, según tengo entendido.

man 7 socketno documenta esto como parte de SO_REUSEADDRlo que hizo que esta respuesta fuera difícil de entender.

información relacionada