2016-06-02 1 views
0

Je configure une connexion StreamWriter/StreamReader à partir d'un NetworkStream pour contrôler un équipement de test. La connexion sous-jacente est TCP.C# StreamWriter/NetworkStream/TcpClient/Ne pas envoyer de données après une période d'inactivité de +5 min

Dans ce cas particulier, cette connexion reste inactive pendant plusieurs minutes. Après que +5 minutes passent, quand j'appelle streamWriter.writeLine(...), alors vider, aucune donnée n'est envoyée de mon ordinateur à l'équipement de test (regarder des paquets sur wireshark). Avant et pendant le temps d'inactivité, aucun paquet n'est échangé. Aucun FIN ou paquets RST, etc ...

Débogage mon objet streamWriter, il semble être encore valide (connected = true, etc ...)

Je rencontre des problèmes d'identification quelle partie de mon StreamWriter/NetworkStream/TcpClient l'objet se déconnecte ou se ferme sans envoyer un message FIN ou RST pour fermer formellement la connexion.

Voici une version abrégée du code qui échoue:

private void button1_Click(object sender, EventArgs e) 
{ 
     TcpClient client; 
     NetworkStream networkStream; 
     System.IO.StreamReader streamReader; 
     System.IO.StreamWriter streamWriter; 
     string outputString; 

     client = new TcpClient("555.555.555.555", 5025); 
     client.ReceiveTimeout = 5000; 
     networkStream = client.GetStream(); 
     streamReader = new System.IO.StreamReader(networkStream); 
     streamWriter = new System.IO.StreamWriter(networkStream); 

     //This section works fine, every time 
     streamWriter.WriteLine("*IDN?\n");  //Ask for equipment identification 
     streamWriter.Flush(); 
     outputString = streamReader.ReadLine(); 
     Console.WriteLine("First Attempt: Connected to: {0}", outputString); 

     System.Threading.Thread.Sleep(301000); //Simulate idle connection time 

     //The read in this section fails if the sleep above is longer than 5 minutes 
     streamWriter.WriteLine("*IDN?\n");  //Ask for equipment identification 
     streamWriter.Flush(); 
     outputString = streamReader.ReadLine(); 
     Console.WriteLine("Second Attempt: Connected to: {0}", outputString); 
} 

L'erreur se trouve lorsque je tente de lire la réponse en retour de ce que je rédigeai à l'équipement. Parce que l'équipement n'a jamais vu ma demande, j'obtiens une erreur de délai de lecture.

Si je change de sommeil en moins de 5 minutes, tout fonctionne correctement. J'ai envisagé d'implémenter une sorte de keep alive sur le socket, mais je crois comprendre que nativement, une connexion TCP restera ouverte jusqu'à ce que l'une des extrémités la ferme. Je ne crois pas non plus qu'il s'agisse d'un problème de réseau tiers car Wireshark montre qu'aucun message FIN ou RST n'a été envoyé/reçu et que ma tentative d'écriture d'un message après 5 minutes n'est pas vue par Wireshark, qui est fonctionne aussi sur mon ordinateur. Je cours Microsoft Visual Studio 2010 sur mon ordinateur Windows 7, si cela aide.

Toutes les recommandations seraient grandement appréciées. S'il vous plaît laissez-moi savoir si j'ai besoin d'expliquer les détails ou de clarifier quelque chose.

+0

J'ai eu le même problème. Ce n'est pas un problème avec votre code. Quelque chose entre les périphériques nettoie les connexions inactives (probablement un pare-feu stateful?). Ajout d'un keepalive (10 minutes était suffisant dans mon cas) était la seule solution que j'ai pu trouver. – itsme86

+0

vaut la peine d'essayer * juste au cas où * - définir 'NoDelay' sur le client tcp –

+0

Avec quelques excavations supplémentaires, j'ai désactivé mon logiciel anti-virus 'Symantec' et ne pouvais plus recréer le problème. Il semblerait que la politique sur mon ordinateur, mis en place par le département informatique, va fermer une connexion inactive. Dans le but de bien jouer avec la politique, je vais implémenter une simple vérification de timing où si la dernière connexion a été utilisée il y a plus d'un certain temps, je vais fermer et rouvrir la connexion. – Peter

Répondre

0

Ce problème a été résolu en implémentant une vérification de temps qui fermait et rétablissait la connexion si plus de quelques minutes se passaient sans trafic. Cela est dû au fait que le logiciel anti-virus qui s'exécutait sur l'ordinateur hôte était proactif, sans notification préalable, mettant fin aux connexions inactives.