Question

I receive the follow exception:

System.NotSupportedException : This stream does not support seek operations.
   at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.BufferedStream.FlushRead()
   at System.IO.BufferedStream.WriteByte(Byte value)

The follow link show that this is a known problem for microsoft. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

This stacktrace show 2 things:

  1. The System.IO.BufferedStream do some absurd pointer move operation. A BufferedStream should buffer the underlying stream and not more. The quality of buffer will be bad if there are such seek operation.
  2. It will never work stable with a stream that not support Seek.

Are there any alternatives? Does I need a buffer together with a NetworkStream in C# or is this already buffered.

Edit: I want simply reduce the number of read/write calls to the underlying socket stream.

Was it helpful?

Solution

The solution is to use two independent BufferedStreams, one for receiving and one for sending. And don't forget to flush the sending BufferedStream appropriately.


Since even in 2018 it seems hard to get a satisfying answer to this question, for the sake of humanity, here are my two cents:

The NetworkStream is buffered on the OS side. However, that does not mean there are no reasons to buffer on the .net side. TCP behaves well on Write-Read (repeat), but stalls on Write-Write-Read due to delayed ack, etc, etc.

If you, like me, have a bunch of sub-par protocol code to take into the twentyfirst century, you want to buffer.

Alternatively, if you stick to the above, you could also buffer only reads/rcvs or only writes/sends, and use the NetworkStream directly for the other side, depending on how broken what code is. You just have to be consistent!

What BufferedStream docs fail to make abundantly clear is that you should only switch reading and writing if your stream is seekable. This is because it buffers reads and writes in the same buffer. BufferedStream simply does not work well for NetworkStream.

As Marc pointed out, the cause of this lameness is the conflation of two streams into one NetworkStream which is not one of .net's greatest design decisions.

OTHER TIPS

The NetworkStream is already buffered. All data that is received is kept in a buffer waiting for you to read it. Calls to read will either be very fast, or will block waiting for data to be received from the other peer on the network, a BufferedStream will not help in either case.

If you are concerned about the blocking then you can look at switching the underlying socket to non-blocking mode.

A BufferedStream simply acts to reduce the number of read/write calls to the underlying stream (which may be IO/hardware bound). It cannot provide seek capability (and indeed, buffering and seeking are in many ways contrary to eachother).

Why do you need to seek? Perhaps copy the stream to something seekable first - a MemoryStream or a FileStream - then do your actual work from that second, seekable stream.

Do you have a specific purpose in mind? I may be able to suggest more appropriate options with more details...

In particular: note that NetworkStream is a curiosity - with most streams, read/write relate to the same physical stream; however, a NetworkStream actually represents two completely independent pipes; read and write are completely unrelated. Likewise, you can't seek in bytes that have already zipped past you... you can skip data, but that is better done by doing a few Read opdrations and discarding the data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top