为什么这两个 StreamWriter 构造函数会给我不同的结果?

Why do these two StreamWriter constructors give me different results?

长话短说,我正在尝试使用 StreamWriter 通过 TcpClient 发送字符串。

除了换出这些示例外,不更改任何其他代码。他们产生不同的结果。

在代码示例 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 为真?

知道为什么吗?

问题是您的 ReadToEnd() 命令无限期地阻塞在 NetworkStream 上,直到关闭才结束。我测试了您的代码,并通过了 DataAvailable 查询并阻止了 ReadToEnd() 命令。

您的方法使用允许 BaseStream 保持打开状态的构造函数,这意味着您的流永远不会结束。当工作方法关闭流时,ReadMessage 方法 returns 与流中的所有内容。

解决办法:不要试图读到最后。在数据可用时读取块或引入终止字符并读取到该字符。

来自MSDN:

ReadToEnd assumes that the stream knows when it has reached an end. For interactive protocols in which the server sends data only when you ask for it and does not close the connection, ReadToEnd might block indefinitely because it does not reach an end, and should be avoided.