web-dev-qa-db-fra.com

Comment correctement et complètement fermer/réinitialiser une connexion TcpClient?

Quel est le bon moyen de fermer ou de réinitialiser une connexion TcpClient?.

J'ai essayé de forcer TcpClient.Close () et même de le mettre à null mais cela ne fonctionne pas . Seul un redémarrage complet du logiciel fonctionne.

Suggestions?


Je ne peux pas utiliser le mot-clé using car TpcClient n'est défini qu'à un seul emplacement, mais est utilisé dans toute la bibliothèque. (Et il n'y a qu'une seule connexion à la fois)

C'est une bibliothèque qui gère la communication. Le logiciel lui-même peut appeler la méthode ResetConnection () de la classe Controller (qui représente le matériel).

Il ressemble actuellement à

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

Maintenant, d'après ce que j'ai lu ici, je devrais utiliser tcpClient.Dispose () au lieu de "= null"

Je vais essayer et voir si cela fait une différence.

64
TimothyP

Vous devez fermer le flux avant de fermer la connexion:

tcpClient.GetStream().Close();
tcpClient.Close();

La fermeture du client ne ferme pas le flux.

74

Étant donné que la réponse acceptée est obsolète et que je ne vois rien dans les autres réponses à ce sujet, j'en crée une nouvelle. Dans .Net 2 et versions antérieures, vous deviez fermer manuellement le flux avant de fermer la connexion. Ce bogue est corrigé dans toutes les versions ultérieures de TcpClient en C # et comme indiqué dans la documentation de la méthode Close un appel à la méthode Close ferme à la fois la connexion et le flux.

EDIT selon Microsoft Docs

La méthode Close marque l'instance comme étant supprimée et demande à ce que le Socket associé ferme la connexion TCP. Basé sur le LingerState propriété, la connexion TCP peut rester ouverte quelque temps après le La méthode Close est appelée lorsqu'il reste des données à envoyer. Il n'y a pas notification fournie lorsque la connexion sous-jacente est terminée fermeture.

L'appel de cette méthode aboutira éventuellement à la fermeture du Socket associé et fermera également le NetworkStream associé utilisé pour envoyer et recevoir des données, le cas échéant.

21
John Demetriou

Utilisez Word: using . Une bonne habitude de programmation.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}
20
Michał Ziober

Ferme une connexion de socket et permet de réutiliser le socket:

tcpClient.Client.Disconnect(false);
7
Justin Tanner

La bonne façon de fermer le socket pour pouvoir rouvrir est la suivante:

tcpClient.Client.Disconnect(true);

Le paramètre Boolean indique si vous souhaitez réutiliser le socket:

 Disconnect method usage

4
Kevin Gigiano

À l’exception d’une journalisation interne, Fermer == Éliminer.

Supprime les appels tcpClient.Client.Shutdown (SocketShutdown.Both), mais il mange des erreurs . Peut-être que si vous l'appelez directement, vous pouvez obtenir des informations utiles sur les exceptions.

4
jyoung

Bien que nous ayons toutes les instructions using appropriées, appelant Close, possédant une logique de suppression exponentielle et recréant la TcpClient, je rencontrais toujours des problèmes pour lesquels l’application ne pouvait pas récupérer la connexion TCP sans redémarrage de l’application. Il continue à échouer avec un System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote Host.

Mais il existe une option LingerState sur la TcpClient qui semble avoir résolu le problème (elle risque de ne pas être connue avant quelques mois, car ma propre configuration matérielle échoue à peu près aussi souvent!). Voir MSDN

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...
2
Ian Mercer

Avez-vous essayé d'appeler TcpClient.Dispose () explicitement?

Et êtes-vous sûr d’avoir TcpClient.Close () et TcpClient.Dispose () - ed ALL connexions?

0
chakrit