.NET TcpClient 空&非空 return 流

.NET TcpClient Empty & Non empty return stream

当有数据返回时,下面的工作正常。但是,返回一个空流是有效的,此时下面的内容挂在 stream.read() 上。我如何重构它以满足这两种情况?

        using(TcpClient client = new TcpClient(_server, _port))
        using(NetworkStream stream = client.GetStream())
        {
            stream.Write(data, 0, data.Length);

            byte[] myReadBuffer = new byte[1024];

            int numberOfBytesRead = 0;

            var message = new List<Byte> ();

            do{
                numberOfBytesRead = stream.Read(myReadBuffer, numberOfBytesRead, myReadBuffer.Length);

                message.AddRange(myReadBuffer.Take(numberOfBytesRead));

            }
            while(stream.DataAvailable);         

            return message.ToArray();
        }

如果我对代码示例的理解正确,那么您真正想要做的就是从套接字(即 TCP 连接)读取所有字节,然后 return 它们作为 byte[]。如果是这样就更好了:

    using(TcpClient client = new TcpClient(_server, _port))
    using(NetworkStream stream = client.GetStream())
    using(MemoryStream output = new MemoryStream())
    {
        stream.CopyTo(output);
        return output.ToArray();
    }

作为一般规则,我强烈建议不要使用DataAvailable 属性。在这种情况下,它特别不合适,因为它所做的只是检查可以从流中读取多少字节,如果它不为零,则 returns true。空流永远不会有可用字节,就此而言,即使流不为空,您也永远不会检测到流的结尾(即无法判断另一端何时完成向您发送数据)。

如果我误解了你真的只想 return 立即可用的字节,那么我无法在没有更多上下文的情况下提供答案。 正确的实现方法是使用异步I/O,其中一个层理解流的整体结构(即数据边界在哪里),但需要详细信息实施您的问题中不存在的内容,因此无法提供具体的建议。

您永远无法判断是否会有更多数据到来或流是否已耗尽。远端 必须 向您发出流结束的信号。

通过关闭或关闭套接字,您将读取 0 个字节,这是您停止读取的信号。

或者,让远端发送数据流结束信号。

您对 DataAvailable 的使用是一个错误(99% 的此类使用都是错误)。 DataAvailable是毒药。它告诉您现在有多少数据准备好以非阻塞方式读取。 1us 之后答案可能不同。

你需要把这个扔掉。