简体   繁体   English

C#-NetworkStream.Read-填充整个缓冲区的正确方法(否则抛出异常)

[英]C# - NetworkStream.Read - correct way to fill the entire buffer (or throw exceptions otherwise)

The NetworkStream.Read method documentation states that it returns zero on two cases: NetworkStream.Read方法文档指出在两种情况下它返回零:

  • "If no data is available for reading, the Read method returns 0." “如果没有可用的数据读取,则Read方法将返回0。”
  • "If the remote host shuts down the connection, and all available data has been received, the Read method completes immediately and return zero bytes." “如果远程主机关闭连接,并且已收到所有可用数据,则Read方法将立即完成并返回零字节。”

And also there is the following observation: 还有以下观察:

Check to see if the NetworkStream is readable by calling the CanRead property. 通过调用CanRead属性来检查NetworkStream是否可读。 If you attempt to read from a NetworkStream that is not readable, you will get an IOException. 如果您尝试从不可读的NetworkStream读取,则会得到IOException。

I'm very confused about it. 我对此很困惑。 How do I know that I can keep reading or that I should stop trying to read? 我怎么知道我可以继续阅读或者应该停止阅读?

Take the following sample method: 采取以下示例方法:

void Receive(byte[] buffer)
{
    int idx = 0;
    while (idx < buffer.Length)
    {
        if (input.CanRead)
        {
            int read = input.Read(buffer, idx, buffer.Length - idx);

            if (read == 0)
            {
                // ???
            }

            idx += read;
        }
        else
        {
            throw new MyLibConnectionClosedException("Cannot receive because the connection was closed");
        }
    }
}

It should fill the entire buffer or it should throw an exception (if the connection was closed or lost). 它应该填满整个缓冲区或抛出异常(如果连接已关闭或丢失)。 What is the correct way to do that? 正确的方法是什么?

Taking an evidence based approach to establishing the facts... If you look at the source code for Stream.CopyTo , which relies on method Stream.InternalCopyTo you'll see the following code for copying one stream to another: 采用基于证据的方法来建立事实...如果您查看Stream.CopyTo的源代码,它依赖于Stream.InternalCopyTo方法, Stream.InternalCopyTo您将看到以下代码将一个流复制到另一个流:

byte[] buffer = new byte[bufferSize];
int read;
while ((read = Read(buffer, 0, buffer.Length)) != 0)
    destination.Write(buffer, 0, read);

This makes it absolutely clear to me that 0 represents the end of stream and not that "there is nothing to read now". 这对我来说绝对清楚, 0代表流的结束,而不是“现在没有任何内容可读取”。

Any suggestion that a return value of 0 has a second meaning is incorrect, as this would make the implementation of CopyTo incorrect. 关于返回值0具有第二个含义的任何建议都是不正确的,因为这会使CopyTo的实现不正确。

In short, to read a stream to the end, carry on reading until Read returns 0 (or an exception is thrown). 简而言之,要读取流的末尾,请继续读取直到Read返回0 (否则引发异常)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM