Comment puis-je vérifier si un (TCP) socket (dis)connecté en C#?
Comment dois-je vérifier un (TCP) prise pour savoir si il est connecté?
J'ai lu sur la Socket.Connected
propriété dans MSDN, mais il dit qu'il ne montre que l'état selon le dernier I/O. Ce n'est pas utile pour moi, car je veux faire ce avant essayer de lire à partir de la douille. La section remarques note également que:
Si vous avez besoin pour déterminer le courant
état de la connexion, faire un
non bloquantes, de zéro octet Envoyer l'appel. Si
les retours d'appel avec succès ou
jette un WAEWOULDBLOCK code d'erreur
(10035), puis le socket est toujours
connecté; sinon, le socket est pas
plus connecté.
L'exemple sur la même page montre comment le faire.(1) Mais un post par Ian Griffiths dit que je devrais lire de la prise, de ne pas envoyer à travers elle.
Un autre post par Pete Duniho dit:
... après que vous avez appelé
Shutdown()
,
appelReceive()
jusqu'à ce qu'il retourne0
(en supposant que le point de terminaison distant n'est pas
en réalité, va vous envoyer quoi que ce soit,
que se produira dès que la distance
point de terminaison a reçu la totalité de votre
de données). Sauf si vous le faites, vous avez
aucune assurance que le point de terminaison distant
a reçu toutes les données
vous avez envoyé, même à l'aide d'une longue
socket.
Je ne comprends pas vraiment sa déclaration à propos de l'appel de Receive()
pour s'assurer que le point de terminaison distant a reçu toutes les données que je envoyé. (Ne sockets bloc de réception jusqu'à l'envoi de la mémoire tampon est vide?)
Je suis confus par les différentes méthodes proposées. Pourriez-vous nous expliquer?
(1) je me demande pourquoi le exemple pour la Socket.Connected
propriété alloue un 1-tableau d'octets, même si elle appelle Send
avec 0 longueur?
- Suivez ce lien...à la fin, vous pouvez trouver une procédure pour que stackoverflow.com/questions/1387459/...
Vous devez vous connecter pour publier un commentaire.
La mort d'un socket de ses changements de comportement de plusieurs façons, afin que ces méthodes sont à la fois valables 🙂
Avec les deux méthodes vous avez réellement vérifier les parties de la prise du comportement qui changent après la déconnexion.
TCP
est fiable protocole, ce qui signifie que tous les paquets que vous envoyez doit être reconnu. La reconnaissance implique l'envoi de paquets avecACK
ensemble de bits. Ces paquets peuvent ou ne peuvent pas contenir d'autres (charge) de données.Lorsque la socket est connecté,
Receive()
bloquera jusqu'à ce que le support reçoit un paquet avec des non-vide charge utile. Mais quand la prise est débranchée,Receive()
sera de retour dès que le dernierACK
paquet arrive.Appel
Receive()
assure que vous recevoir ce dernierACK
paquet à partir de votre point de terminaison distant ou un délai de déconnexion se produit et vous serez en mesure de recevoir rien de plus sur cette prise.Quand
send()
ing à un socket, vous avez réellement essayez d'ajouter des données à la fin de la prise de la file d'attente. Est il y a de la place à gauche dans la mémoire tampon, puis votreSend()
retourne instantanément, si non, laSend()
blocs jusqu'à ce qu'il y a de la place.Quand le support est en état déconnecté,
TCP/IP
pile empêche toutes les autres opérations de la mémoire tampon, c'est pourquoiSend()
renvoie une erreur.Send()
met en œuvre une base pointeur de la case, cela signifie qu'il échoue lorsqu'unNULL
pointeur est passé. Vous pouvez probablement passer toute non-constante null comme un pointeur, mais il vaut mieux allouer 1 octet au lieu de faire de la constante de haut — juste au cas où.Vous pouvez utiliser n'importe quelle méthode que vous aimez, comme aucun d'eux n'est coûteuse en termes de ressources. Aussi longtemps qu'ils sont utilisés pour la connexion de socket de la vérification, ils sont identiques.
Quant à moi, je préfère
Receive()
, que c'est ce que vous exécutez normalement dans un cycle et d'attendre. Vous obtenez un zéro deReceive()
, vous traiter les données; vous obtenez un zéro, vous le processus de déconnexion."Si vous avez besoin de déterminer l'état actuel de la connexion, effectuer un non bloquantes, de zéro octet Envoyer l'appel. Si les retours d'appel avec succès ou jette un WAEWOULDBLOCK code d'erreur (10035), puis le socket est toujours connecté, sinon, le support n'est plus connecté." -- malheureusement, il ne fonctionne même pas!
bConnected finit toujours aussi vrai, et l'appel retourne toujours avec succès, même si le câble Ethernet est débranché.
De plus, et malheureusement, = = envoi de toutes les données réelles ne détecte pas la connexion interrompue, soit.
à plusieurs reprises retourne 1, comme s'il avait effectivement envoyé quelque chose. Alors que l'appareil en question n'est même pas connecté.
Généralement on utilise le Socket.Sélectionnez la méthode pour déterminer l'état d'un ensemble de prises de courant (Socket.Sondage pour une seule prise).
Ces deux méthodes vous permettent d'interroger une prise de son état. Maintenant, en supposant que vous avez suivi la prise connectée en premier lieu, puis vous le feriez habituellement appel Select/Poll sur le support avant d'essayer de le lire. Si Select/Poll indiquent que la prise de la lisibilité de ce qui vous dit que:
Personnellement je n'ai jamais utilisé Sondage - j'ai toujours utilisé, mais MSDN semble suggérer que le Sondage est à peu près la même que pour Sélectionner, mais pour une seule sockets.
Je vais aussi ajouter que dans la plupart des cas à l'aide de Select est la plus efficace et la meilleure façon de gérer les connexions Socket.
Le post de @PeteDuniho n'est pas à propos de l'établissement de l'état de la connexion, il est à propos de mettre fin à la connexion de telle sorte que vous savez quand les pairs a reçu toutes vos données.
Non, mais si vous arrêtez la prise et ensuite de lire jusqu'à EOS, vous êtes en attente pour les pairs de lire toutes les données jusqu'à ce que il obtient EOS, puis ferme la socket. Si vous avez une garantie que toutes les données ont pénétré dans l'application par les pairs.