1

I'm trying to make a function which takes a Stream(any type of stream, NetworkStream,FileStream, etc...) and write a byte array then reads the array, for this case I'm using BinaryWriter and BinaryReader. The writing part works fine, I simply the BinaryWriter.Write function. but the reader part seems to raise an issue, especially when I use a NetworkStream. I couldn't find a way to read all the bytes from stream. so I was wondering if it's even possible to read all bytes from a NetworkStream while treating it as an object of type Stream. I could cast it to a socket then work with socket functions but I wonder if there's a way to write code that can work both with NetworkStream and other type of streams. these are the two functions: Issue is inside first case, in the Deserialize method

        public static void Serialize(Stream stream, object obj)
        {
            BinaryWriter writer = new BinaryWriter(stream);
            switch (Compression)
            {
                case FormatCompression.Binary:
                    writer.Write(BinaryDeconstructor.Deconstruct(obj));
                    break;
                case FormatCompression.String:
                    writer.Write(Deconstructor.Deconstruct(obj));
                    break;
                default:
                    throw new SerializationException("Please choose a format compression");
            }
            writer.Flush();
        }

        public static object Deserialize(Stream stream)
        {
            BinaryReader reader = new BinaryReader(stream);
            switch (Compression)
            {
                case FormatCompression.Binary:
                    byte[] packet = /*HOW?!*/;
                    object obj = BinaryConstructor.Construct(packet);
                    return obj;
                case FormatCompression.String:
                    //this case works fine
                    string objGraphData = reader.ReadString();
                    return Constructor.Construct(objGraphData);
                default:
                    throw new SerializationException("Please choose a format compression");
            }
        }

1 Answer 1

1

The problem with the network stream is that you don't know when to stop reading and start deserializing. That's easy to fix, though: if you pass the number of bytes to read ahead of serializing the array, the reader could read the number first, because the number occupies a fixed number of bytes, and then use that number to read the actual bytes of the array.

Figuring out the number of bytes gets a little tricky. It can be solved by serializing into a temporary memory buffer, harvesting the buffer size, sending the size, and finally send the actual array of bytes, which you now have in memory:

// Writing
var writer = new BinaryWriter(stream);
switch (Compression) {
    case FormatCompression.Binary:
        var memStream = new MemorySteam();
        var memWriter = new BinaryWriter(memStream);
        memWriter.Write(BinaryDeconstructor.Deconstruct(obj));
        memWriter.Flush();
        writer.Write(memStream.Length);
        writer.Write(memStream.GetBuffer());
        break;
    case FormatCompression.String:
        writer.Write(Deconstructor.Deconstruct(obj));
        break;
    default:
        throw new SerializationException("Please choose a format compression");
}
writer.Flush();

Now your binary deserialization code has access to an int that represents the parameter that you pass to the method that reads a specified number of bytes from your stream of any kind. Note that if you would like to use this code in a production situation, you must validate the length that comes off the wire to avoid an attacker passing a too large or a negative number to your program through this protocol.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.