Pregunta

Estaba leyendo sobre el uso de la opción de socket SO_LINGER para 'asesinar' intencionalmente el estado de tiempo de espera estableciendo el tiempo de permanencia en cero.El autor del libro continúa diciendo que nunca deberíamos hacer esto y, en general, que nunca deberíamos interferir con el estado de tiempo de espera.Luego recomienda inmediatamente usar la opción SO_REUSEADDR para evitar el estado de tiempo de espera.

Mi pregunta es ¿cuál es la diferencia?En ambos casos, finalizará prematuramente el estado de espera y correrá el riesgo de recibir segmentos duplicados.¿Por qué uno es bueno y el otro malo?

¿Fue útil?

Solución 2

Leí un poco más y esta es mi comprensión de lo que sucede (con suerte, correcta):

Cuando llamas a close en un socket que tiene SO_REUSEADDR configurado (o tu aplicación falla), se produce la siguiente secuencia:

  1. TCP Envía cualquier dato restante en el búfer de envío y un FIN
  2. Si se llamó a cerrar, regresa inmediatamente sin indicar si los datos restantes se entregaron correctamente.
  3. Si se enviaron datos, el par envía un ACK de datos.
  4. El par envía un ACK del FIN y envía su propio paquete FIN
  5. Se confirma el FIN del par y se desasignan los recursos del socket.
  6. El socket no entra en TIME-WAIT.

Cuando cierras un socket con el tiempo SO_LINGER establecido en cero:

  1. TCP descarta cualquier dato en el buffer de envío
  2. TCP envía un paquete RST al par
  3. Los recursos de socket se desasignan.
  4. El socket no entra en TIME-WAIT

Entonces, más allá del hecho de que establecer la permanencia en cero es un truco y un mal estilo, también es de mala educación, ya que no realiza un cierre limpio de la conexión.

Otros consejos

TIME_WAIT es absolutamente normal. Se produce después de un FIN de TCP en el lado local seguido de un TCP FIN ACK desde la ubicación remota. En TIME_WAIT que está a la espera de los paquetes perdidos para llegar a la dirección local. Sin embargo, si hay un paquete perdido o extraviado a continuación, asegúrese de que TIME_WAIT TTL o "tiempo de vida" expira antes de utilizar la dirección de nuevo.

Si utiliza SO_REUSEADDR entonces usted está diciendo básicamente, voy a suponer que no hay paquetes perdidos. Que es cada vez más probable con las redes modernas, fiables y TCP. Aunque todavía es posible, es poco probable.

Configuración SO_LINGER a cero que hace que para iniciar un cierre anormal, también llamado "cerrando la conexión." Aquí no se respeta TIME_WAIT y hacer caso omiso de la posibilidad de un paquete perdido.

Si ves FIN_WAIT_1 entonces esto puede causar problemas, ya que la ubicación remota no ha enviado una red TCP FIN ACK en respuesta a su FIN. Por lo que el proceso se mató a uno o TCP FIN ACK se perdió debido a una partición de red o un mal camino.

Cuando vea CLOSE_WAIT usted tiene un problema, aquí se filtra la conexiones que no está enviando el FIN de TCP ACK cuando se le da el TCP FIN.

Tengo utilizar SO_REUSEADDR de comodín bind () a un puerto local para el que algún otro programa ya tenía una conexión abierta en. Resulta que este uso particular no causará un problema, siempre y cuando no hay dos tomas tratan de escuchar () en el mismo combo addr / puerto al mismo tiempo.

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