.NET TcpClient Empty&非空返回流

时间:2015-02-07 18:09:08

标签: c# .net tcpclient

当有数据返回时,以下工作正常。但是,对于返回空流是有效的,此时下面会挂起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();
        }

2 个答案:

答案 0 :(得分:1)

如果我正确理解了代码示例,那么您真正要做的就是从套接字读取所有字节(即TCP连接),然后将它们作为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属性。在这种情况下,它特别不合适,因为它所做的只是检查可以从流中读取多少字节,如果它不为零,则返回true。空流将永远不会有字节可用,并且就此而言,即使流不为空,也永远不会检测到流的结束(即,无法判断另一端何时完成向您发送数据)。

如果我误解了你真的只想返回立即可用的字节,那么我就无法在没有更多上下文的情况下提供答案。 正确实现这一目的的方法是使用异步I / O,其中一个层可以理解流的整体结构(即数据边界所在的位置),但是实现它的细节是'如果您的问题存在,那么就不可能提供具体的建议。

答案 1 :(得分:1)

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

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

或者,让远程端发送数据信号通知流的末尾。

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

你需要扔掉它。