Vérification pour une déconnexion du client sur une Java serveur TCP - sortie uniquement
J'ai un Java serveur TCP qui, lorsqu'un client se connecte à elle, affiche un message au client toutes les 30 secondes. C'est une exigence stricte que le client n'envoie pas les messages sur le serveur et que le serveur n'envoie pas d'autres données que les intervalles de 30 secondes des messages au client.
Lorsque je déconnecte le client, le serveur ne se rendront pas compte jusqu'à ce que la prochaine fois qu'il tente d'écrire pour le client. Ainsi, il peut prendre jusqu'à 30 secondes pour que le serveur de reconnaître les débrancher.
Ce que je veux faire est de vérifier pour la déconnecter toutes les quelques secondes sans avoir à attendre, mais je ne suis pas sûr de savoir comment faire cela, étant donné que le serveur ne reçoit pas de la part du client et b) le serveur ne peut pas envoyer d'autres données. Quelqu'un aurait-il s'il vous plaît être en mesure de faire la lumière sur cette? Merci.
OriginalL'auteur Myn | 2011-03-10
Vous devez vous connecter pour publier un commentaire.
Même si votre serveur n'a pas "recevoir" de la part du client, non-blocage de la lecture sur la socket client vous dira qu'il n'y a rien à lire (comme prévu), ou que le client s'est déconnecté.
Si vous utilisez NIO vous pouvez simplement utiliser un non-bloquant
Selector
en boucle (avec les sockets non bloquant) et seulement écrire sur votre deuxième de 30 marques. Si unSelectionKey
est lisible et la lire sur leSocketChannel
retourne -1, vous savez que le client s'est déconnecté.EDIT: une Autre approche avec le blocage est tout simplement à sélectionner avec un délai d'attente de 30 secondes. Tout client se déconnecte sera la cause de la sélectionner pour revenir et vous saurez qui ceux sont par l'intermédiaire de la lire ensemble. La chose supplémentaire que vous devez faire est de suivre combien de temps vous avez été bloqué dans le sélectionner pour savoir quand faire votre écrit sur les 30 secondes (Réglage de la temporisation pour la prochaine sélectionnez le delta).
Big Edit: Après avoir parlé à Myn ci-dessous, offrant exemple complet:
Intéressant de noter ici est que la
PrintWriter
vraiment vous déplace loin de la réelle prise, et vous n'allez pas attraper la prise de déconnexion sur l'écriture (Il ne sera jamais lever une exception, vous devez vérifier manuellement aveccheckError()
) Vous pouvez modifier à l'aide d'unBufferedWriter
à la place (nécessite l'utilisation deflush()
à repousser la sortie) et le traitant comme leBufferedReader
pour attraper une discothèque sur l'écriture.Merci Brian. Je ne suis pas à l'aide de NIO, est-il toujours possible d'utiliser un non-blocage de lire? J'ai également essayé d'utiliser
setSoTimeout()
mais cela ne semble pas fonctionner quand je force le client à proximité, qui est un de mes tests.Est-il une raison pour laquelle vous ne l'utilisez pas NIO? Il est disponible depuis 2002 et qui fait vraiment votre problème trivial. Je n'avais pas pensé à la façon dont nous avons eu à le faire avant de NIO dans un temps long; il y n'était pas un véritable non-blocage de lire avant que ou un
select()
. Vous êtes sur la bonne voie avecsetSoTimeout()
parce que c'est le seul moyen que vous avez. Vous devriez être en mesure de les appeler pour qu'avant la lecture de votre prise, et il va jeter unInterruptedIOException
si elle arrive à expiration. Plutôt compliqué, mais si vous pouvez utiliser NIO je peux vous donner un exemple de comment cela fonctionne.Et êtes-vous gérer plusieurs connexions de socket à votre serveur, ou seulement un seul?
Oups, en effet, il jette un
java.net.SocketTimeoutException
, juste essayé.OriginalL'auteur Brian Roach
Si vous êtes à la gestion de plusieurs clients, alors je suppose que vous seriez en utilisant les sockets Non Bloquant (Si pas alors envisager l'utilisation de Non-Bloquant). Vous pouvez utiliser le Sélecteur pour contrôler tous les sockets connectées pour vérifier si elles sont lisibles ou inscriptible ou il y a une Erreur sur ce socket. Lorsqu'un client se déconnecte, votre Sélecteur de marque de cette prise et sera de retour.
Pour plus d'aide de google "Socket Sélectionnez la fonction"
OriginalL'auteur Tayyab