Why does the stream not support the seek operation?

后端 未结 2 1539
执笔经年
执笔经年 2021-01-18 11:54

I\'m currently working with tcp/ip suite. I\'m writing a program to encrypt files at sender\'s end and decrypt at receiver\'s side. I came across this exception while initia

相关标签:
2条回答
  • 2021-01-18 12:05

    It is the normal state for a Stream. You need to mentally model it like a small desert river in the spring, trickling water like a Stream is trickling bytes. You don't know when it is going to dry up, that requires a weather forecast that faithfully predicts when it is going to stop raining.

    Such weather forecasts certainly exist. No trouble if it is actually a MemoryStream, it has access to all the bytes so it can reliably tell you when it dries up. Or a FileStream, now the operating system's file system can provide the forecast. The directory entry for the file data records the length of the file.

    It gets to be a lot harder for TCP streams. The TCP protocol itself doesn't provide the information at all. You can only keep calling the socket's Read() method and when it returns 0 then you know it stopped raining.

    This often requires building a protocol on top of TCP. The very common HTTP protocol is a good example. It does provide you with the forecast, it is HttpWebRequest.ContentLength. Or you make your own, the standard technique is to have the transmitter first write 4 bytes that says how much data follows. But NetworkStream doesn't cater to specific protocol implementations, it models a generic network stream. You have to add the weather forecast yourself.

    0 讨论(0)
  • 2021-01-18 12:19

    To determine the length of a stream, you need to be able to read to the end of it (i.e. you Seek to the end). Since this is a network stream, you can't just do this, hence the error you're experiencing. You will need to just keep reading bytes into a buffer until the stream ends, and only then will you know the length of your payload. Here's a suggestion:

    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();
    }
    

    Note that I would also recommend adding using statements for each of your stream instantiations, as this guarantees that the streams will be closed properly even if an exception is thrown while reading/writing. You could then remove the explicit calls to Close.

    0 讨论(0)
提交回复
热议问题