Pregunta

Creo que entiendo el significado formal de la opción. En algún código heredado estoy manejando ahora, se utiliza la opción. El cliente se queja de RST como respuesta a FIN desde su lado en la estrecha relación desde su lado.

No estoy seguro de que puede eliminar de forma segura, ya que no entiendo cuando se debe utilizar.

Puede por favor dar un ejemplo de cuándo se requiere la opción?

¿Fue útil?

Solución

La razón típica para establecer un tiempo de espera SO_LINGER de cero es para evitar un gran número de conexiones que se sientan en el estado TIME_WAIT, atando todos los recursos disponibles en el servidor.

Cuando una conexión TCP se cierra limpiamente, el extremo que inició la cerca ( "close activo") termina con la conexión que se sienta en TIME_WAIT durante varios minutos. Así que si su protocolo es uno donde el servidor inicia la conexión de cierre, e implica un gran número de conexiones de corta duración, entonces podría ser susceptible a este problema.

Esto no es una buena idea, sin embargo - TIME_WAIT existe por una razón (para asegurar que los paquetes perdidos de conexiones antiguas no interfieren con las nuevas conexiones). Es una mejor idea para rediseñar su protocolo a uno donde los iniciados cliente cierre la conexión, si es posible.

Otros consejos

Para mi sugerencia, por favor leer la última sección:. “Al utilizar SO_LINGER con tiempo de espera de 0”

Antes de llegar a que un poco de charla sobre: ??

  • Terminación normal TCP
  • TIME_WAIT
  • FIN, ACK y RST

Terminación normal TCP

la secuencia de terminación TCP normales es similar al siguiente (simplificado):

Tenemos dos compañeros: A y B

  1. A llama close()
    • A envía FIN a B
    • Una pasa al estado FIN_WAIT_1
  2. B recibe FIN
    • B envía ACK a A
    • B pasa al estado CLOSE_WAIT
  3. A recibe ACK
    • Una pasa al estado FIN_WAIT_2
  4. B llama close()
    • B envía FIN a A
    • B pasa al estado LAST_ACK
  5. A recibe FIN
    • A envía ACK a B
    • Una pasa al estado TIME_WAIT
  6. B recibe ACK
    • B pasa al estado CLOSED - es decir, se elimina de las tablas de zócalo

TIME_WAIT

Así que el par que inicia la terminación - es decir, las llamadas close() primera -. Va a terminar en el estado TIME_WAIT

Para entender por qué el estado TIME_WAIT es nuestro amigo, por favor lea la sección 2.7 en la "Red UNIX Programación" tercera edición por Stevens et al (página 43).

Sin embargo, puede haber un problema con un montón de tomas de corriente en el estado de TIME_WAIT en un servidor, ya que con el tiempo podría evitar nuevas conexiones sean aceptados.

Para evitar este problema, he visto muchos sugiriendo para establecer la opción de socket SO_LINGER con tiempo de espera antes de llamar a 0 close(). Sin embargo, esta es una mala solución, ya que hace que la conexión TCP para ser terminada con un error.

En su lugar, el diseño de su protocolo de aplicación por lo que la finalización de la conexión se inicia siempre desde el lado del cliente. Si el cliente siempre sabe cuando se ha leído todos los datos restantes se puede iniciar la secuencia de terminación. A modo de ejemplo, un navegador sabe desde el Content-Length cabecera HTTP cuando se ha leído todos los datos y puede iniciar el cierre. (Sé que en HTTP 1.1 que va a mantenerlo abierto durante un tiempo para una posible reutilización, y luego cerrarlo.)

Si las necesidades de los servidores para cerrar la conexión, diseñar el protocolo de aplicación para que el servidor pide al cliente que close() llamada.

¿Cuándo utilizar SO_LINGER con tiempo de espera 0

Una vez más, de acuerdo con "Red UNIX Programación" tercera página 202-203 edición, el establecimiento de SO_LINGER con tiempo de espera de 0 antes de llamar close() hará que la secuencia de terminación normal no para ser iniciado.

En su lugar, el establecimiento de esta opción y llamando close() enviará un RST (restablecimiento de conexión) entre pares que indica una condición de error y esta es la forma en que se percibe en el otro extremo. Por lo general, verá errores como "Conexión reajustada por el par".

Por lo tanto, en la situación normal es una muy mala idea establecer SO_LINGER con tiempo de espera de 0 antes de llamar close() - de ahora en adelante llamado abortiva cerca -. En una aplicación de servidor

Sin embargo, ciertos situación justifica Si lo hace, de todas formas:

  • Si el cliente de sus porta mal Application Server (tiempo de espera, devuelve datos no válidos, etc.) una estrecha abortiva tiene sentido para evitar ser atrapado en CLOSE_WAIT o acabar en el estado TIME_WAIT.
  • generacodi
  • Si debe reiniciar el servidor de aplicaciones que actualmente cuenta con miles de conexiones de cliente que podría considerar el establecimiento de esta opción zócalo para evitar que miles de sockets de servidor en TIME_WAIT (al llamarcetagcode desde el extremo del servidor) ya que esto podría impedir que el servidor de conseguir puertos disponibles para nuevas conexiones de cliente después de ser reiniciado.
  • En la página 202 en el libro antes mencionado específicamente dice: "Hay ciertas circunstancias que justifican el uso de esta función para enviar una estrecha abortiva Un ejemplo es un servidor de terminal RS-232, lo que podría colgar para siempre en close() tratando de entregar los datos. a un puerto terminal de pegado, sino que reinicia correctamente el puerto atascado si consiguió una CLOSE_WAIT a descartar los datos pendientes. "

Yo recomendaría este artículo largo que creo que da una muy buena respuesta a su pregunta.

Cuando Linger está encendido, pero el tiempo de espera es cero la pila TCP no espera a la espera de los datos que se enviarán antes de cerrar la conexión. Los datos podrían perderse debido a esto, pero estableciendo Linger esta manera usted está aceptando esto y pidiendo que la conexión se restablece de inmediato en lugar de cerrarse con gracia. Esto provoca un RST que se enviará en lugar de la habitual FIN.

Gracias a EJP para su comentario, ver aquí para más detalles.

Si usted puede quitar el Linger en su código de seguridad o no, depende del tipo de su aplicación: se trata de un “cliente” (conexiones apertura TCP y cerrar de forma activa por primera vez) o se trata de un “servidor” (escuchar a una TCP abierta y cerrándola detrás de otro lado inició el cierre)?

Si la aplicación tiene el sabor de un “cliente” (cerrando primero) y que inicie y cerca de un gran número de conexiones a diferentes servidores (por ejemplo, cuando su aplicación es una aplicación de seguimiento que supervise la accesibilidad de un gran número de diferentes servidores ) su aplicación tiene el problema de que todas las conexiones del cliente están atrapados en estado TIME_WAIT. Entonces, yo recomendaría para acortar el tiempo de espera a un valor menor que el valor predeterminado a todavía se cierren correctamente, sino liberar los recursos del cliente conexiones antes. Yo no establecer el tiempo de espera en 0, 0 como no lo hace se cierren correctamente con FIN pero abortiva con RST.

Si la aplicación tiene el sabor de un “cliente” y tiene que traer una enorme cantidad de archivos pequeños desde el mismo servidor, no debe iniciar una nueva conexión TCP por archivo y terminan en una gran cantidad de conexiones de cliente en TIME_WAIT, pero mantener la conexión abierta y buscar a todos los datos sobre la misma conexión. Linger opción puede y debe ser eliminado.

Si su aplicación es un “servidor” (cercano segundo lugar como reacción a cerca de pares), en una estrecha () la conexión se cierra con gracia y se liberan recursos que no se introduce estado TIME_WAIT. Linger no debe ser utilizado. Pero si su aplicación Sever tiene un proceso de supervisión para detectar conexiones abiertas inactivas idleing durante mucho tiempo ( “largo” es definir) Puede apagar esta conexión inactiva de su lado - verlo como una especie de control de errores - con un cierre fallido. Esto se hace mediante el establecimiento de tiempo de espera Linger a 0. close () se enviará un RST para el cliente, diciéndole que usted está enojado: -)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top