Est-il possible de fermer les sockets Java côté client et côté serveur?


J'ai une connexion tcp socket entre deux applications java. Lorsqu'un côté ferme la prise, l'autre côté reste ouvert. mais je veux qu'il soit fermé. Et aussi j'ai hâte de voir s'il est disponible ou non et après cela, fermez-le. J'ai besoin de le fermer complètement d'un côté. Que puis-je faire?

Author: Tshepang, 2010-01-30

5 answers

TCP ne fonctionne pas comme ça. Le système d'exploitation ne libérera pas les ressources, à savoir le descripteur de fichier et donc le port, jusqu'à ce que l'application ferme explicitement le socket ou meurt, même si la pile TCP sait que l'autre côté l'a fermé. Il n'y a pas de rappel du noyau à l'application utilisateur à la réception de la FIN de l'homologue. Le système d'exploitation le reconnaît de l'autre côté mais attend que l'application appelle close() avant d'envoyer son paquet FIN. Jetez un oeil au diagramme de transition d'état TCP - vous êtes dans la case fermeture passive.

Une façon de détecter une situation comme celle-ci sans dédier un thread à chaque socket est d'utiliser la famille de fonctions select/poll/epoll/kqueue. Le socket étant fermé passivement sera signalé comme lisible et la tentative de lecture retournera l'EOF.

J'espère que cela aide.

 10
Author: Nikolai Fetissov, 2016-08-13 18:01:58

Les deux côtés doivent lire à partir de la connexion, afin qu'ils puissent détecter quand le pair est fermé. Lorsque read renvoie -1, cela signifie que l'autre extrémité a fermé la connexion et que c'est votre indice pour fermer votre extrémité.

 6
Author: nos, 2010-01-29 22:40:50

Si vous lisez toujours à partir de votre socket, vous détecterez le -1 à sa fermeture.

Si vous ne lisez plus depuis votre socket, allez-y et fermez-le.

Si ce n'est ni l'un ni l'autre, vous avez probablement un thread en attente sur un événement. Ce n'est PAS la façon dont vous voulez gérer des milliers de ports! Java commencera à obtenir pukey à environ 3000 threads sous Windows much beaucoup moins sous Linux (je ne sais pas pourquoi).

Assurez-vous que vous utilisez NIO. Utilisez un seul thread pour gérer tous vos ports (pool de connexions). Il devrait simplement récupérer les données d'un thread, les transmettre à une file d'attente. À ce stade, je pense qu'un pool de threads supprimerait les données des files d'attente et les traiterait car le traitement des données à partir d'un port prendrait un certain temps.

Attacher un thread à chaque port ne fonctionnera PAS, et est la principale raison pour laquelle NIO était nécessaire.

De plus, avoir une sorte de message "Fermer" dans le cadre de votre flux pour déclencher la fermeture du port peut faire fonctionner les choses plus rapide--mais vous devrez toujours gérer le -1 pour couvrir le cas des flux cassés

 4
Author: Bill K, 2010-01-29 22:53:40

La solution habituelle est de faire savoir à l'autre côté que vous allez fermer la connexion, avant de la fermer réellement. Par exemple, dans le cas du protocole SMTP, le serveur enverra "221 Bye" avant de fermer la connexion.

 3
Author: Confusion, 2010-01-29 22:57:14

Vous voulez probablement avoir un pool de connexions.

 -1
Author: Roman, 2010-01-29 22:48:54