为什么流不支持搜索操作?

时间:2014-04-27 09:26:29

标签: c# networkstream

我目前正在使用tcp / ip套件。我正在编写一个程序来加密发件人端的文件并在接收方进行解密。我在使用网络流的长度初始化我的字节数组时遇到了这个异常。这是我的代码:

if (client.Connected)
{
    NetworkStream binarystream = client.GetStream();
    byte[] receivebytes = new byte[binarystream.Length];
    binarystream.Read(receivebytes, 0, receivebytes.Length);
    Stream file = File.OpenWrite(saveFileDialog1.FileName);
    file.Write(receivebytes, 0, receivebytes.Length);
    file.Close();
    binarystream.Close();
}

控制层次结构确保client.GetStream()返回的流在构成二进制流实例之前已经用过。我得到的例外情况包含:

byte[] receivebytes = new byte[binarystream.Length];

它表示流不支持搜索操作。这是什么意思?

2 个答案:

答案 0 :(得分:7)

这是Stream的正常状态。你需要在春天像一条小沙漠河流那样进行精神上的模拟,像溪流一样涓涓细流的水。你不知道什么时候会干涸,需要一个天气预报,忠实地预测它什么时候会停止下雨。

这样的天气预报确实存在。没有问题,如果它实际上是一个MemoryStream,它可以访问所有字节,这样它可以可靠地告诉你什么时候它干了。或者FileStream,现在操作系统的文件系统可以提供预测。文件数据的目录条目记录文件的长度。

TCP流变得更加困难。 TCP协议本身根本不提供信息。您只能继续调用套接字的Read()方法,当它返回0时,您就知道它已停止下雨。

这通常需要在TCP之上构建协议。非常常见的HTTP协议就是一个很好的例子。它确实为您提供了预测,它是HttpWebRequest.ContentLength。或者你自己制作,标准技术是让发射机首先写入4个字节,说明后面有多少数据。但NetworkStream并不适合特定的协议实现,它为通用网络流建模。你必须自己添加天气预报。

答案 1 :(得分:1)

要确定流的长度,您需要能够读到它的末尾(即您Seek到最后)。由于这是一个网络流,您不能只这样做,因此您遇到的错误。您需要继续将字节读入缓冲区,直到流结束,然后才能知道有效负载的长度。这是一个建议:

if (client.Connected)
{
    NetworkStream binarystream = client.GetStream();
    Stream file = File.OpenWrite(saveFileDialog1.FileName);

    byte[] buffer = new byte[10000];
    int bytesRead;
    while (binarystream.DataAvailable)
    {
        bytesRead = binarystream.Read(buffer, 0, buffer.Length);
        file.Write(buffer, 0, bytesRead);
    }

    file.Close();
    binarystream.Close();
}

请注意,我还建议为每个流实例添加using语句,因为这可以保证即使在读/写时抛出异常也会正确关闭流。然后,您可以删除对Close的显式调用。