[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