长话短说我试图通过TcpClient使用StreamWriter发送字符串。
除了更换这些样本外,不更改任何其他代码。它们会产生不同的结果。
在代码示例1 中,StreamReader选择它具有DataAvailable并收到消息。
在代码示例2 中,它没有DataAvailable,因此不会收到任何消息。我需要保持我的底层流打开,因此需要在示例2中使用StreamWrite的构造函数。
示例1 - 写入方法
public void SendMessage(string message)
{
message = "TestMessage";
//WORKING - Sample 1
using (var sw = new StreamWriter(stream))
{
sw.Write(message);
sw.Flush();
}
}
示例2 - 写入方法
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?
任何想法都是为什么?
答案 0 :(得分:1)
问题是你的ReadToEnd()
命令在NetworkStream
无限期地阻塞,直到关闭才结束。我测试了你的代码,然后我超越了DataAvailable
查询并在ReadToEnd()
命令上被阻止。
使用允许BaseStream
保持打开的构造函数的方法意味着您永远不会结束流。当工作方法关闭流时,ReadMessage
方法返回流中的所有内容。
解决方案:不要尝试阅读到最后。在数据可用时读入块或引入终止字符并读取该字符。
来自MSDN:
ReadToEnd假设流知道它何时到达终点。对于服务器仅在您请求数据并且不关闭连接时发送数据的交互式协议,ReadToEnd可能会无限期地阻塞,因为它没有达到目的,应该避免。