2017-10-12 106 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可能会无限期地阻塞,因为它没有达到结束,应该避免。

相关问题