[Mono-list] Socket code.

Jonathan Gilbert 2a5gjx302@sneakemail.com
Mon, 23 Feb 2004 10:21:06


At 11:59 AM 22/02/2004 -0800, you wrote:
>On Sun, 2004-02-22 at 01:17, Michal Moskal wrote:
>> On Sat, Feb 21, 2004 at 04:31:00PM -0800, George Farris wrote:
>> > I have some socket code that looks something like this:
>> > 
>> > byte[] bytes = new byte[1448];
>> > do {
>> > 	len = sock.Read(bytes, 0, (int)1448);
>> > 	s = Encoding.ASCII.GetString(bytes);
>> > 	buf.Append(s.Substring(0,len));
>> 
>
>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.

Jonathan