Est-il possible qu'une connexion TCP reste ouverte lorsque le client s'est déconnecté?

12

Nous avons une application serveur qui fait face à des problèmes d'épuisement TCP à environ 4000 connexions. Cela se produira toutes les 3 ou 4 semaines (environ). Le fournisseur, qui a créé cette application serveur, nous dit, après avoir examiné la sortie de netstat -b, que certaines connexions restent ouvertes même si les clients sont tombés.

J'ai été chargé d'étudier pourquoi une application cliente particulière ne ferme pas correctement la connexion TCP. Je suis convaincu que si un ordinateur client est arrêté, il ne peut PAS éventuellement signaler depuis le serveur qu'une connexion TCP est toujours établie avec ce client. Malheureusement, je ne trouve aucune information pour valider ma vue. Je ne veux pas perdre plus de temps à enquêter sur un problème potentiel qui, je pense, ne peut même pas être un problème.

tldr;

Un serveur peut-il signaler une connexion établie à un ordinateur qui est éteint?

Josh Smeaton
la source

Réponses:

13

TCP ne fait aucun effort pour détecter une connexion morte, sauf d'un côté qui transmet des données. C'est la responsabilité du code d'application appelant dans la pile TCP de le faire. Quel protocole est impliqué ici? (Celui au-dessus de TCP.)

C'est une "solution" horriblement laide, mais vous pouvez activer les keepalives TCP . Il y a plus dans cet article .

David Schwartz
la source
Vous vouliez probablement dire couche et sa couche de session au-dessus de la couche de transport, où TCP réside.
Rilindo
1
@Rilindo: En pratique, et dans ce cas particulier, vous avez une application qui fait des appels à la pile TCP. Le protocole au-dessus de TCP (HTTP, POP ou autre) spécifie généralement comment procéder, car les concepteurs de ces protocoles savaient que TCP ne pouvait pas le faire lui-même.
David Schwartz
Oups, mon erreur. Sa couche 7, alors.
Rilindo
Je ne vais pas activer les keepalives à ce stade, mais il est utile de savoir que l'option existe. Cet article semble suggérer qu'il existe déjà un délai de 2 heures. AFAIK, les connexions sont maintenues ouvertes pendant des jours / semaines.
Josh Smeaton
Très probablement, les keepalives ne sont pas activés. Un morceau de code doit les activer. Il semble que l'application soit tout simplement cassée si elle n'active même pas keepalives et n'a pas de mécanisme de temporisation / récolte. De quel protocole parlons-nous? (HTTP? SMTP? FTP?)
David Schwartz
8

Oui c'est possible. Comme David et Paul l'ont déclaré dans leurs réponses, il n'y a pas de mécanisme dans TCP (à part TCP keep-alives, qui sont facultatifs) pour détecter une connexion semi-ouverte. Il appartient au fournisseur de l'application de déterminer l'état de la connexion et de prendre les mesures appropriées en conséquence.

En ce qui concerne TCP, il n'y a pas de détection ou de distinction entre une connexion semi-ouverte et une longue connexion inactive.

Vous devrez commencer à résoudre ce problème de la couche 1 (physique) du modèle OSI jusqu'à la couche 7 (application) pour déterminer où le problème se produit. Mon conseil serait d'installer et d'exécuter un programme de capture de paquets sur l'un des clients concernés jusqu'à ce que le problème se produise, puis d'analyser la capture pour essayer de déterminer ce qui fait que le client ne ferme pas la connexion.

joeqwerty
la source
3
Ou demandez au vendeur d'implémenter des délais raisonnables :)
Shane Madden
5

Lorsqu'un poste de travail souhaite fermer une connexion avec un serveur, il envoie un TCP FIN. Si le client ne se comporte pas correctement et ne ferme pas ses connexions, il pourrait en effet rester établi sur le serveur. Vous pouvez définir des délais d'expiration pour les connexions ouvertes sur le serveur pour les nettoyer - bien qu'il serait préférable de trouver la cause. Dans quel port les connexions ouvertes entrent-elles? Une fois que vous savez à quel service vous accédez, vous pourrez peut-être identifier l'application client qui frappe le serveur.

Paul Ackerman
la source
Nous savons que le client est le problème apparent. Il s'agit d'une application de bureau que des centaines de nos utilisateurs utilisent quotidiennement. Je suppose que le problème est le blocage de l'application, une réinitialisation matérielle ou une tâche de fin. J'ai pensé dans toutes ces situations que le serveur serait au courant de la connexion interrompue.
Josh Smeaton
4
En ce qui concerne le serveur, la connexion est ouverte sauf s'il reçoit un FIN ou un RST du client. Sans cela, le serveur suppose que la connexion est toujours établie mais que le client n'a pas de données à envoyer. Il n'y a aucune différence entre une connexion semi-ouverte et une connexion inactive en ce qui concerne le serveur.
joeqwerty
@joeqwerty: Vrai, mais le serveur pourrait décider qu'il ne souhaite pas maintenir une connexion ouverte indéfiniment et pourrait implémenter un mécanisme de délai d'expiration / fermeture. C'est ce que David Schwartz voulait dire dans sa réponse par "c'est la responsabilité du code d'application". Le serveur peut donc faire la différence entre une connexion semi-ouverte et une connexion inactive s'il le souhaite. Pour TCP cependant, il n'y a en effet aucune différence entre une connexion semi-ouverte et une connexion inactive.
sleske
@sleske: convenu que le code de l'application pourrait le faire, mais TCP ne peut pas le faire sauf si la persistance est activée.
joeqwerty