2017-10-12 103 views
0

長話短說我想通過使用StreamWriter的TcpClient發送一個字符串。這兩個StreamWriter構造函數爲什麼會給我不同的結果?

不更改任何其他代碼,只是交換這些樣本。他們產生不同的結果。

在代碼示例1中,StreamReader發現它具有DataAvailable並且接收到消息。

代碼示例2它沒有DataAvailable,因此沒有收到消息。我需要讓我的基礎流開,因此需要使用StreamWrite的構造樣品2

樣品1 - Write方法

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

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

樣品2 - Write方法

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(); 
     } 
    } 

閱讀方法

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

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

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

注意:如果我把兩個樣本放在一起工作最後我收到消息「TestMessageTestMessage」,所以它肯定是寫入流,但它不是設置DataAvailable爲true?

任何想法的原因是什麼?

+1

請提供一個在工作和非工作狀態下的完整示例。在SendMessage和ReadMessage之間很難分辨你正在做什麼。 –

+0

它與問題沒有直接關係,但https://stackoverflow.com/questions/27961274/reading-information-from-a-port-waits-even-though-data-available的答案可能會給你另一種方法比依靠DataAvailable屬性。 –

+0

你是否在調用write方法後立即調用read方法?在這種情況下,DataAvailable屬性在您檢查時可能尚未設置。嘗試把線程。在你的書寫和閱讀之間休息(100),看看它是否有效。 –

回答

1

問題是你的ReadToEnd()命令無限期地阻止NetworkStream,直到關閉時才結束。我測試了您的代碼,並且我通過了DataAvailable查詢並在ReadToEnd()命令中被阻止。

您使用允許BaseStream保持打開狀態的構造函數的方法意味着您永遠不會終止流。當工作方法關閉流時,ReadMessage方法返回流中的所有內容。

解決方案:不要試圖讀到最後。在數據可用時讀取數據塊,或者引入終止字符並讀取該字符。

MSDN:

ReadToEnd的假設,當它已經到頭流知道。對於服務器只在需要時才發送數據並且不關閉連接的交互式協議,ReadToEnd可能會無限期地阻塞,因爲它沒有達到結束,應該避免。

相關問題