¿Es posible que una conexión TCP permanezca abierta cuando el cliente se ha desconectado?

12

Tenemos una aplicación de servidor que enfrenta problemas de agotamiento de TCP en alrededor de 4000 conexiones. Esto ocurrirá cada 3 o 4 semanas (aproximadamente). El proveedor, que ha creado esta aplicación de servidor, nos dice después de examinar la salida de netstat -b que algunas conexiones permanecen abiertas incluso si los clientes se han caído.

Me dieron la tarea de investigar por qué una aplicación de cliente en particular no está cerrando la conexión TCP correctamente. Creo que si una computadora cliente se apaga, no puede informar POSIBLEMENTE desde el servidor que todavía se establece una conexión TCP con ese cliente. Lamentablemente, no puedo encontrar ninguna información para validar mi punto de vista. No quiero perder más tiempo investigando un problema potencial que no creo que pueda ser un problema.

tldr;

¿Puede un servidor informar una conexión establecida a una computadora que está apagada?

Josh Smeaton
fuente

Respuestas:

13

TCP no hace ningún esfuerzo para detectar una conexión inactiva, excepto en un lado que está transmitiendo datos. Es responsabilidad del código de la aplicación llamar a la pila TCP para hacer esto. ¿Qué protocolo está involucrado aquí? (El que está encima de TCP).

Es una "solución" horriblemente fea, pero puedes habilitar TCP keepalives . Hay más en este artículo .

David Schwartz
fuente
Probablemente quisiste decir capa y es la capa de sesión encima de la capa de transporte, que es donde reside TCP.
Rilindo
1
@Rilindo: en la práctica, y en este caso particular, tiene una aplicación que realiza llamadas a la pila TCP. El protocolo sobre TCP (HTTP, POP o lo que sea) generalmente especifica cómo hacer esto, porque los diseñadores de esos protocolos sabían que TCP no podía hacerlo por sí mismo.
David Schwartz
Vaya, mi error. Su capa 7, entonces.
Rilindo
No voy a habilitar keepalives en este momento, pero es útil saber que existe la opción. Ese artículo parece sugerir que ya existe un tiempo de espera de 2 horas. AFAIK, las conexiones se mantienen abiertas durante días / semanas.
Josh Smeaton
Lo más probable es que los keepalives no estén habilitados. Algún fragmento de código tiene que habilitarlos. Parece que la aplicación simplemente está rota si ni siquiera habilita keepalives y no tiene un mecanismo de tiempo de espera / cosecha. ¿De qué protocolo estamos hablando? (HTTP? SMTP? FTP?)
David Schwartz
8

Sí, es posible. Como David y Paul declararon en sus respuestas, no hay ningún mecanismo en TCP (que no sea TCP keep-alives, que es opcional) para detectar una conexión medio abierta. Depende del proveedor de la aplicación determinar el estado de la conexión y tomar las medidas adecuadas en consecuencia.

En lo que respecta a TCP, no hay detección ni distinción entre una conexión medio abierta y una conexión inactiva larga.

Tendrá que comenzar a solucionar este problema desde la capa 1 (física) del modelo OSI hasta la capa 7 (aplicación) para averiguar dónde está ocurriendo el problema. Mi consejo sería instalar y ejecutar un programa de captura de paquetes en uno de los clientes afectados hasta que ocurra el problema, y ​​luego analizar la captura para tratar de determinar qué está causando que el cliente no cierre la conexión.

joeqwerty
fuente
3
O haga que el vendedor implemente tiempos de espera razonables :)
Shane Madden
5

Cuando una estación de trabajo desea cerrar una conexión con un servidor, envía un FIN de TCP. Si el cliente no se comporta correctamente y no cierra sus conexiones, de hecho podrían permanecer establecidos en el servidor. Puede establecer tiempos de espera para conexiones abiertas en el servidor para limpiarlas, aunque sería mejor encontrar la causa. ¿En qué puerto están entrando las conexiones abiertas? Una vez que sepa a qué servicio se está accediendo, podrá identificar la aplicación cliente que está llegando al servidor.

Paul Ackerman
fuente
Conocemos al cliente que es el problema aparente. Es una aplicación de escritorio que cientos de nuestros usuarios usan a diario. Supongo que el problema es el bloqueo de la aplicación, un restablecimiento completo o una tarea final. Sin embargo, pensé en todas esas situaciones que el servidor sería consciente de la conexión caída.
Josh Smeaton el
44
En lo que respecta al servidor, la conexión está abierta a menos que reciba un FIN o un RST del cliente. Sin eso, el servidor supone que la conexión aún está establecida pero que el cliente no tiene datos para enviar. No hay diferencia entre una conexión medio abierta y una conexión inactiva en lo que respecta al servidor.
joeqwerty
@joeqwerty: Cierto, sin embargo, el servidor podría decidir que no desea mantener abierta una conexión indefinidamente y podría implementar algún mecanismo de tiempo de espera / cierre. A eso se refería David Schwartz en su respuesta con "es responsabilidad del código de la aplicación". Por lo tanto, el servidor puede marcar la diferencia entre una conexión medio abierta y una conexión inactiva si así lo desea. Sin embargo, para TCP, de hecho, no hay diferencia entre una conexión medio abierta y una conexión inactiva.
sleske
@sleske: acordó que el código de la aplicación podría hacer esto, pero TCP no puede hacerlo a menos que se habilite la función de mantenimiento.
joeqwerty