[Mono-list] System.Net.Sockets.NetowrkStream Flaw/Inconsistency/Wierdness

Scott Manley scott@imeem.com
Tue, 03 Aug 2004 14:35:13 -0700

So the NetworkStream class sits on top of  the Socket class and provides 
a stream like interface, one of the methods has a problem which probably 
needs fixing to make the class halfway useful.

The Write method is supposed to let us write data to an open stream and 
does this by calling Send on the underlying socket.....

        public override void Write (byte [] buffer, int offset, int size)
            try {
                socket.Send (buffer, offse, size, 0);
            } catch (Exception e) {
                throw new IOException ("Write failure", e);

However it's possible for Send to write less than the requested amount 
of data to the socket, it returns the number of bytes written - since 
the Write method returns void we should be ensuring the write is 
complete before leaving the function. Otherwise you end up like me and 
spend hours wondering why NetworkStream objects sometimes lose data.....
So we need to wrap our socket.Send with enough logic to handle 
potentially multiple writes...

                int fragoff = 0;
                while (fragoff < size )
                    if(socket.Poll(-1, SelectMode.SelectWrite)) {     
                         int written = socket.Send (buffer, offset + 
fragoff, size - fragoff, 0);
                         fragoff += written;
                     } else {
                         throw new IOException ("Socket not writeable");

Furthermore the BeginWrite/EndWrite methods suffer from the same 
problem, I think in this case a lock will be needed to ensure we handle 
multiple requests in order and without letting data get mixed up.

Does this all make sense or am I just making krazy talk.

Scott Manley