number linux sockets port ip-address setsockopt

linux - number - port 8081



¿Cuál es el significado de SO_REUSEADDR(opción setsockopt)-Linux? (3)

Desde la página man:

SO_REUSEADDR Especifica que las reglas utilizadas para validar las direcciones suministradas a bind () deberían permitir la reutilización de las direcciones locales, si esto es compatible con el protocolo. Esta opción toma un valor int. Esta es una opción booleana

¿Cuándo debería usarlo? ¿Por qué la "reutilización de direcciones locales" da?


SO_REUSEADDR permite que su servidor se vincule con una dirección que está en un
Estado de TIME_WAIT.

Esta opción de socket le dice al kernel que incluso si este puerto está ocupado (en el estado TIME_WAIT), adelante y reutilícelo de todos modos. Si está ocupado, pero con otro estado, aún recibirá una dirección que ya está en uso. Es útil si su servidor se ha apagado y luego se ha reiniciado de inmediato mientras los sockets todavía están activos en su puerto.

De unixguide.net


Cuando creas un socket, realmente no lo tienes. El sistema operativo (pila TCP) lo crea para usted y le proporciona un identificador (descriptor de archivo) para acceder a él. Cuando el socket está cerrado, lleva tiempo que el sistema operativo "lo cierre completamente" mientras atraviesa varios estados. Como EJP mencionó en los comentarios, la demora más larga suele ser del estado TIME_WAIT. Se requiere este retraso adicional para manejar las cajas de borde al final de la secuencia de finalización y asegurarse de que la última confirmación de terminación haya finalizado o que el otro lado se haya reiniciado debido a un tiempo de espera excedido. Aquí puede encontrar algunas consideraciones adicionales sobre este estado. Las principales consideraciones se señalan a continuación:

Recuerde que TCP garantiza que se entregarán todos los datos transmitidos, si es posible. Cuando cierra un socket, el servidor entra en un estado TIME_WAIT, solo para estar realmente seguro de que se han procesado todos los datos. Cuando se cierra un socket, ambas partes acuerdan enviándose mensajes de que no enviarán más datos. Esto, me pareció que era lo suficientemente bueno, y después de que se haya hecho el apretón de manos, el socket debería estar cerrado. El problema es doble. En primer lugar, no hay forma de estar seguro de que el último ack se comunicó con éxito. Segundo, puede haber "duplicados errantes" en la red que deben ser tratados si se entregan.

Si intentas crear varios sockets con el mismo par de ip: puerto realmente rápido, obtienes el error de "dirección que ya está en uso" porque el socket anterior no se habrá liberado por completo. El uso de SO_REUSEADDR eliminará este error, ya que anulará las comprobaciones de cualquier instancia anterior.


El objetivo principal del diseño de TCP es permitir una comunicación de datos confiable frente a la pérdida de paquetes, el reordenamiento de paquetes y, clave, aquí, la duplicación de paquetes.

Es bastante obvio cómo una pila de red TCP / IP se ocupa de todo esto mientras la conexión está activa, pero hay un caso extremo que ocurre justo después de que se cierra la conexión. ¿Qué sucede si un paquete enviado justo al final de la conversación está duplicado y retrasado, de modo que los paquetes de apagado de 4 vías llegan al receptor antes del paquete retrasado? La pila cierra diligentemente su conexión. Luego, más tarde, aparece el paquete duplicado retrasado. ¿Qué debería hacer la pila?

Más importante aún, ¿qué debería hacer si el programa que poseía esa conexión muere inmediatamente, y luego otro comienza a querer la misma dirección IP y el mismo número de puerto TCP?

Hay un par de opciones:

  1. No permita la reutilización de ese combo IP / puerto por lo menos 2 veces el tiempo máximo que un paquete puede estar en vuelo. En TCP, esto generalmente se llama retraso 2 × MSL . A veces también ves 2 × RTT , que es más o menos equivalente.

    Este es el comportamiento predeterminado de todas las pilas TCP / IP comunes. 2 × MSL es típicamente entre 30 y 120 segundos. (Este es el período TIME_WAIT ). Después de ese tiempo, la pila asume que cualquier paquete fraudulento se ha eliminado en el camino debido a TTLs caducados, por lo que deja el estado TIME_WAIT , lo que permite que se reutilice ese IP / puerto combinado.

  2. Permita que el nuevo programa vuelva a unirse a ese IP / combo de puerto. En las pilas con interfaces de sockets BSD , esencialmente todos los sistemas Unix y similares a Unix, más Windows a través de Winsock , debe solicitar este comportamiento estableciendo la opción SO_REUSEADDR través de setsockopt() antes de llamar a bind() .

SO_REUSEADDR se configura generalmente en programas de servidor.

La razón es que un patrón común es que cambie un archivo de configuración del servidor y necesite reiniciarlo para que vuelva a cargar su configuración. Sin SO_REUSEADDR , la llamada bind() en la nueva instancia del programa reiniciado fallará si hubiera conexiones abiertas a la instancia anterior cuando la eliminó. Esas conexiones mantendrán el puerto TCP en el estado TIME_WAIT durante 30-120 segundos, por lo que se cae en el caso 1 anterior.

Lo más seguro es esperar el período TIME_WAIT , pero en la práctica no es un riesgo lo suficientemente grande como para que valga la pena hacerlo. Es mejor hacer una copia de seguridad del servidor inmediatamente para no perder más conexiones entrantes de las necesarias.