[Mono-list] Socket code.

Piers Haken piersh@friskit.com
Mon, 23 Feb 2004 09:17:04 -0800


I'm not sure why you're checking for specific lengths of bytes returned at
all.

This is what I use:

string Read (Stream stream)
{
	StringBuilder sb = new StringBuilder ();
	byte [] rgb = new byte [8 * 1024];
	int cbRead;
	while ((cbRead = stream.Read (rgb, 0, rgb.Length)) > 0)
		sb.Append (Encoding.ASCII.GetString (rgb, 0, cbRead));
	
	return sb.ToString ();
}

Piers. 

-----Original Message-----
From: mono-list-admin@lists.ximian.com
[mailto:mono-list-admin@lists.ximian.com] On Behalf Of George Farris
Sent: Sunday, February 22, 2004 5:50 PM
To: Mono list
Subject: Re: [Mono-list] Socket code.

On Mon, 2004-02-23 at 02:21, Jonathan Gilbert wrote:
> >Interesting, this code will work as long as the check at the bottom 
> >is 1448, any other number and it croaks???  The buffer can be any 
> >size presumably larger than 1448 and it will work.
> 
> Note (to original poster) that if you want to read up to the end of 
> the stream, you should actually check 'len' against '0':
> 
>   if (len < 0)
>     error_occurred();
>   if (len == 0)
>     end_of_stream_occurred();
> 
> You shouldn't assume that the underlying transport will always be able 
> to deliver chunks of the same size. The 1448 here has most likely to 
> do with the sending computer's TCP/IP stack. Perhaps it ties the TCP 
> packet size into the MTU to decrease fragmentation & increase 
> performance (this is fairly common, as I understand). Assuming this is 
> the case, your problem is simply evidence that, unlike my 'ReadFully' 
> function, 'NetworkStream::Read()' does not try to completely read the 
> requested buffer. Instead, it does one read attempt and then 
> immediately returns. So, you're limited to the size that
'Socket::Receive()' will give you.
> 
> In short, any positive value from 'Socket::Receive()' indicates that 
> there could be additional data waiting; a return value of 0 indicates 
> that the connection was shut down in that direction (thus indicating 
> the end-of-stream). Simply getting a smaller value than you requested 
> does not indicate that the end of the stream has been reached. This is 
> distinctly different from file I/O.
> 
Well I do check for len > 0, here is the entire function, I also understand
about the TCP packet size not being consistent but what I don't understand
is why this actually works only like this?  Seems like a bug in the stream
code.
 
private string read (NetworkStream stream, TcpClient c) {
	int len;
	string s;
	StringBuilder buf = new StringBuilder();
			
	do {
		byte[] bytes = new byte[50000];
		len = stream.Read(bytes, 0, (int)50000);
		if (len > 0 ) {
			s = Encoding.ASCII.GetString(bytes,0,len);
			buf.Append(s);
		}
		if (len < 1448)
			break;
	} while (len > 0);
	
	return buf.ToString();
}

If I take the if (len < 1448) out it doesn't work.  If I change the 1448 to
something else, it doesn't work. 

--
George Farris <george@gmsys.com>

_______________________________________________
Mono-list maillist  -  Mono-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-list