2

What are the possible causes for Stream not Writable Exception when serializing custom object over TCP using Network Stream in C#. I am Sending the Mp3 data in the form of Packets.The Frame consists of Byte[] Buffer.I am Using Binary Formatter to serialize the object.

BinaryFormatter.Serialize(NetworkStream,Packet);

The Mp3 Played at client with distortion and jitters end for few seconds and then The above mentioned exception raised.I m using NAudio Open Source library for it.

Before doing this modification I was using

NetworkStream.Write(Byte[] Buffer,0,EncodedSizeofMp3); and it was writing it successfully before giving any exception

Samie
  • 83
  • 2
  • 11

1 Answers1

3

If you are writing to a NetworkStream, the stream/socket could be closed

If you are writing to a NetworkStream, it could have been created with FileAccess.Read

If I had to guess, though, it sounds like something is closing the stream - this can be the case if, say, a "writer" along the route assumes it owns the stream, so closes the stream prematurely. It is pretty common to have to write and use some kind of wrapper Stream that ignores Close() requests (I have one in front of me right now, in fact, since I'm writing some TCP code).

As a small aside; I generally advise against BinaryFormatter for comms (except remoting) - most importantly: it doesn't "version" in a very friendly way, but it also tends to be a bit verbose in most cases.

Here's the wrapper I'm using currently, in case it helps (the Reset() method spoofs resetting the position, so the caller can read a relative position):

class NonClosingNonSeekableStream : Stream
{
    public NonClosingNonSeekableStream(Stream tail)
    {
        if(tail == null) throw new ArgumentNullException("tail");
        this.tail = tail;
    }

    private long position;
    private readonly Stream tail;
    public override bool CanRead
    {
        get { return tail.CanRead; }
    }
    public override bool CanWrite
    {
        get { return tail.CanWrite; }
    }
    public override bool CanSeek
    {
        get { return false; }
    }
    public override bool CanTimeout
    {
        get { return false; }
    }
    public override long Position
    {
        get { return position; }
        set { throw new NotSupportedException(); }
    }
    public override void Flush()
    {
        tail.Flush();
    }
    public override void SetLength(long value)
    {
        throw new NotSupportedException();
    }
    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotSupportedException();
    }
    public override long Length
    {
        get { throw new NotSupportedException(); }
    }
    public override int Read(byte[] buffer, int offset, int count)
    {
        int read = tail.Read(buffer, offset, count);
        if (read > 0) position += read;
        return read;
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        tail.Write(buffer, offset, count);
        if (count > 0) position += count;
    }
    public override int ReadByte()
    {
        int result = tail.ReadByte();
        if (result >= 0) position++;
        return result;
    }
    public override void WriteByte(byte value)
    {
        tail.WriteByte(value);
        position++;
    }
    public void Reset()
    {
        position = 0;
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • shoudl that network stream in the second line be a filestream? – Chris Feb 03 '12 at 16:10
  • @Chris no; the constructor for NetworkStream accepts a FileAccess to indicate whether the stream (that ultimately just wraps a Socket) is intended for read / write / both; [see MSDN](http://msdn.microsoft.com/en-us/library/6z1c325b.aspx) - or to quote: "The access parameter sets the CanRead and CanWrite properties of the NetworkStream. If you specify Write, then the NetworkStream allows calls to the Write method. If you specify Read, then the NetworkStream allows calls to the Read method. If you specify ReadWrite, both method calls are allowed." – Marc Gravell Feb 03 '12 at 16:16
  • Before doing this modification I was using NetworkStream.Write(Byte[] Buffer,0,EncodedSizeofMp3); and it was writing it successfully before giving any exception – Samie Feb 03 '12 at 17:05
  • @Samie so the question becomes: what happened between the time it worked, and it not working...? – Marc Gravell Feb 03 '12 at 17:07
  • @MarcGravell: Ah, ok. It seemed like an unusual language construct to repeat it so I assumed it must be different. I have to admit I've not done any network programming so I was just guessing. Sorry to have confused. I promise to read that page though to do better next time. ;-) – Chris Feb 03 '12 at 17:24
  • @MarcGravell:May be it was due to Serialization over Network stream,that its not working now – Samie Feb 06 '12 at 04:24