7
votes

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

J'ai une connexion TCP de socket entre deux applications Java. Quand un côté ferme la prise, l'autre côté reste ouvert. Mais je veux que ça soit fermé. Et aussi, j'ai hâte de voir s'il est disponible ou non et après cela. Je veux un moyen de le fermer complètement d'un côté. Que puis-je faire?


0 commentaires

5 Réponses :


6
votes

Les deux côtés doivent lire à partir de la connexion, afin qu'ils puissent détecter lorsque le pair est fermé. Lorsque vous lisez les retours -1, cela signifie que l'autre extrémité fera fermer la connexion et c'est votre indice pour fermer votre fin.


2 commentaires

Mon code est un code multi-threadé et je ne peux pas gaspiller l'un de mes discussions pour simplement regarder la connexion et la recherche de la fermeture ou non. Je devrais mentionner que j'ai des milliers de ces connexions non seulement.


Ensuite, vous devrez passer à Nio et faire du multiplexé IO. Vous devez lire de la prise d'une manière ou une autre si vous souhaitez détecter un gracieux proche de la pair.



-1
votes

Vous voulez probablement avoir un pool de connexion.


1 commentaires

Non, fermez simplement la connexion automatiquement.



4
votes

Si vous lisez toujours à partir de votre prise, vous détecterez le -1 quand il se ferme.

Si vous ne lisez plus de votre prise, allez-y et fermez-la.

Si ce n'est aucun de ceux-ci, vous avez probablement un fil d'attente sur un événement. Ce n'est pas la façon dont vous voulez gérer des milliers de ports! Java commencera à obtenir de Pukey autour de 3000 threads sous Windows - beaucoup moins à Linux (je ne sais pas pourquoi).

Assurez-vous que vous utilisez Nio. Utilisez un seul thread pour gérer tous vos ports (pool de connexion). Cela devrait simplement saisir les données d'un fil, transmettez-la à une file d'attente. À ce stade, je pense que j'aurais une piscine de thread de prendre les données des files d'attente et de le traiter car le traitement des données d'un port prendra du temps.

La fixation d'un fil à chaque port ne fonctionnera pas et la plus grande raison de la Nio était nécessaire.

Aussi, avoir une sorte de message "proches" dans le cadre de votre flux à la fermeture de la fermeture du port peut faire fonctionner les choses plus rapidement - mais vous aurez toujours besoin de gérer le -1 pour couvrir le cas des ruisseaux cassés < / p>


3 commentaires

Ce côté ne sait pas s'il est fini ou non. Envoi également un message proche de la surcharge de l'autre côté est trop. La plupart des temps pour un message, nous envoyons deux messages.


Je ne sais pas ce que vous voulez dire, mais vous pouvez simplement mettre fin à un message avec un caractère spécial ou un bytecode afin de dire à l'auditeur que c'est le dernier message. C'est à peu près gratuit.


Si l'envoi de quelques octets supplémentaires pour signaler une fermeture est trop surcharge, vous avez des exigences très particulières ou vous souffrez d'une optimisation prématurée.



3
votes

La solution habituelle consiste à laisser l'autre côté savoir que vous allez fermer la connexion, avant de la fermer. Par exemple, dans le cas du protocole SMTP, le serveur enverra "221 bye" avant la fermeture de la connexion.


1 commentaires

Bien que ce soit une bonne optimisation, il ne traitera pas les connexions abandonnées et, éventuellement, vous allez empiler des ports ouverts. Ce n'est pas acceptable dans un système avec des milliers de ports ouverts, mais il réduit la fréquence de "puis-je fermer ce port".



10
votes

TCP ne fonctionne pas comme ça. Le système d'exploitation ne libère pas les ressources, à savoir le descripteur de fichier et donc le port, jusqu'à ce que l'application ferme explicitement la prise ou la mort, même si la pile TCP sait que l'autre côté la ferma. Il n'y a pas de rappel du noyau à l'application utilisateur à la réception de la nageoire de la pair. Le système d'exploitation l'accuse à l'autre côté mais attend que l'application appelle fermer () avant d'envoyer son paquet d'aileron. Jetez un coup d'œil au Diagramme de transition de l'état TCP < / a> - Vous êtes dans le passif proche de la boîte .

Un moyen de détecter une situation comme celle-ci sans dédicacer un fil à chaque prise consiste à utiliser le Sélectionner / Poll / Epoll / KQuue famille de fonctions. La prise étant fermée passivement sera signalée comme une tentative lisible et lisible renvoyera le EOF.

J'espère que cela aide.


1 commentaires

Le lien de diagramme de transition de l'état TCP donne un 404