2017-10-12 21 views
0

Longue histoire courte J'essaie d'envoyer une chaîne via TcpClient en utilisant StreamWriter.Pourquoi ces deux constructeurs de StreamWriter me donnent-ils des résultats différents?

Sans changer aucun autre code, à l'exception de l'échange de ces échantillons. Ils produisent des résultats différents.

Dans l'exemple de code 1, StreamReader détecte que DataAvailable est présent et que le message est reçu.

Dans l'exemple de code 2 il ne dispose pas de DataAvailable, donc aucun message n'est reçu. Je dois garder mon flux sous-jacent ouvert donc besoin d'utiliser le constructeur de StreamWrite dans l'échantillon 2.

Exemple 1 - Méthode d'écriture

public void SendMessage(string message) 
    { 
     message = "TestMessage"; 

     //WORKING - Sample 1 
     using (var sw = new StreamWriter(stream)) 
     { 
      sw.Write(message); 
      sw.Flush(); 
     } 
    } 

Exemple 2 - Méthode d'écriture

public void SendMessage(string message) 
    { 
     message = "TestMessage"; 

     //NOT WORKING - Sample 2 
     var encoding = new UTF8Encoding(false, true); 
     using (var sw = new StreamWriter(stream, encoding, 1024, true)) 
     { 
      sw.Write(message); 
      sw.Flush(); 
     } 
    } 

Méthode de lecture

public string ReadMessage() 
    { 
     if (!stream.DataAvailable) 
      return null; 

     //I have also tried 
     //if(sr.Peek() == 0) 
     // return null; 

     string message = sr.ReadToEnd(); 
     return message; 
    } 

NOTE: Si je mets les deux échantillons ensemble avec le dernier en cours de traitement, le message reçu est "TestMessageTestMessage", donc il écrit définitivement dans le flux mais il ne met pas DataAvailable à true?

Une idée c'est pourquoi?

+1

Veuillez fournir un exemple complet à la fois dans l'état de travail et dans l'état non fonctionnel. Il est difficile de dire ce que vous faites entre SendMessage et ReadMessage. –

+0

Il n'est pas directement lié à la question, mais les réponses de https://stackoverflow.com/questions/27961274/reading-information-from-a-port-waits-even-though-data-available pourraient vous donner une autre approche que de s'appuyer sur la propriété DataAvailable. –

+0

Appelez-vous la méthode read juste après avoir appelé la méthode write? Dans ce cas, la propriété DataAvailable n'a peut-être pas été définie au moment de la vérification. Essayez de mettre un fil.Dormez (100) juste entre votre écriture et lire et voir si cela fonctionne. –

Répondre

1

Le problème est votre commande ReadToEnd() qui bloque indéfiniment sur un NetworkStream qui n'a pas de fin jusqu'à ce qu'il soit fermé. J'ai testé votre code et j'ai dépassé la requête DataAvailable et j'ai bloqué la commande ReadToEnd().

Votre méthode qui utilise un constructeur qui permet au de rester ouvert signifie que vous n'avez jamais de fin à votre flux. Lorsque la méthode de travail ferme le flux, la méthode ReadMessage renvoie le tout avec le flux.

La solution: Ne pas essayer de lire jusqu'au bout. Lire dans les blocs pendant que les données sont disponibles ou introduire un caractère de fin et lire à ce caractère.

De MSDN:

ReadToEnd suppose que le flux sait quand il a atteint sa fin. Pour les protocoles interactifs dans lesquels le serveur envoie des données uniquement lorsque vous le demandez et ne ferme pas la connexion, ReadToEnd peut bloquer indéfiniment car il n'atteint pas une fin et doit être évité.