Je cherchais à détecter une "déconnexion du client" lors de l'utilisation d'un TCplistener.
Toutes les réponses semblent être similaires à celle-ci: TCplistener: Comment puis-je détecter un client déconnectez-vous? P>
Fondamentalement, lisez à partir du flux et s'il est lu () renvoie 0 Le client avait déconnecté. P>
Mais cela suppose qu'un client déconnecte après chaque flux de données envoyé. Nous opérons dans des environnements où le TCP Connect / déconnectez les frais généraux est à la fois lent et coûteux. P>
Nous établissons une connexion, puis nous envoyons un certain nombre de demandes. P>
pseudocode: P> Chaque appel entre Connect et Deconnect () envoie un flux de données sur le serveur.
Le serveur sait comment analyser et traiter les flux. P> Si vous laissez le TCplistener lu dans une boucle sans jamais le déconnecter de la lecture et gère tous les messages, mais après la déconnexion du client, le serveur n'a aucun moyen de savoir et
il ne relâchera jamais le client et acceptera de nouvelles. p> si je laisse le TCplistener déposer le client lors de la lecture == 0 Il n'accepte que
Le premier flux de données uniquement pour déposer le client immédiatement après. p> Bien sûr, cela signifie que de nouveaux clients peuvent se connecter. P> Il n'y a pas de retard artificiel entre les appels,
Mais en termes de temps d'ordinateur, le temps entre deux appels est «énorme» bien sûr,
donc il y aura toujours un temps où lire == 0 même si cela ne veut pas dire
Le client a ou doit être déconnecté. p> donc je me demande ... Y a-t-il un meilleur moyen de détecter si le client a déconnecté? P> p>
3 Réponses :
Vous pouvez obtenir la prise sous-jacente à l'aide de la propriété Contrairement à NetworkStream.sockt CODE> et utilisez-la est recevoir la méthode de lecture. p>
NetworkStream.read code>, la surcharge liée de
socket.receive code> bloquera jusqu'à ce que le nombre spécifié d'octets ait été lu et ne reviendra que zéro si l'hôte distant arrête la connexion TCP. p>
NetworkStream.socket code> est une propriété protégée et n'est pas accessible dans ce contexte. Afin d'obtenir le client
code>, vous pouvez utiliser le TCPLISTENER.ACceptsockt Méthode qui renvoie l'objet code> de la prise code> correspondant à la connexion nouvellement établie. P>
NetworkStream.sockt n'est pas exposé octet L'instance de Networkstream renvoyée par tcplistener.getstream (). Mais je cherche maintenant à l'aide de la classe de socket directement
OK, en utilisant les sockets directement et que l'utilisation de la méthode de réception fonctionne comme un charme. Une capture d'essai est nécessaire lors de l'acceptation du client et d'essayer de recevoir. Thnx!
Pourquoi ne vous donne pas accès à Networkstream.sockt code> quand il donne un accès à quasi sans restriction à
tcpclient code> S socket 'S à l'aide du client code> code>? Est-ce juste un .NET DESIGN QUIRIK, ou existe-t-il un scénario où il est logique de ne pas pouvoir obtenir un
socket code> Socket? De plus, vous voudrez peut-être réviser cette réponse car
NetworkStream.socket code> est protégé et non accessible.
@jrh Vous avez raison sur la propriété protégée, j'ai mis à jour la réponse. Très probablement, NetworkStream ne donne pas accès direct à la prise, car elle offre la capacité de limiter les lectures et les écritures. Voir le constructeur Surcharges avec paramètre FileAccess.
La réponse d'Eren a résolu le problème pour moi. Au cas où quelqu'un d'autre est confronté au même problème
Voici un code "échantillon" à l'aide de la méthode Socket.Receive: Vous appelez acceptClientandProcess () dans une boucle quelque part. p> La ligne suivante: p> < Pré> xxx pré> bloquera jusqu'à p> L'une des deux dernières situations indiquez que le client n'est plus connecté. p> L'essais attrape autour de la méthode Socket.Accept () est également requise
Comme il peut échouer si la connexion du client est fermée brusquement pendant la phase de connexion. P> Notez qui spécifie un délai d'attente de 20 secondes pour l'opération de lecture. P> P>
La documentation de Networkstream .Read code>
ne reflète pas cela, mais dans mon expérience, des blocs "Networkstream.Read" si le port est toujours ouvert et qu'aucune donnée n'est disponible, mais renvoie 0 si le port a été fermé. p>
J'ai couru dans Ce problème de l'autre côté , dans ce Networkstream .Read code> ne renvoie pas immédiatement 0 si aucune donnée n'est actuellement disponible. Vous devez utiliser
NetworkStream.DataAnvailable code> pour savoir si
NetworkStream.read code> peut lire des données en ce moment. P>