[comp.sys.sgi] SUMMARY: scrambled network transfers

loki@NAZGUL.PHYSICS.MCGILL.CA (Loki Jorgenson Rm421) (03/29/91)

	Here is the summary to my posting concerning what were seemingly
incomplete and/or scrambled transfers of large amounts of data between
processes across the net.

	In my case, it turned out to be that I was naively assuming that
read() didn't return until it had either timed out or read the amount of
data specified.  Of course, like when reading any other file, read()
will read until EOF which, on a busy net or from a slow machine, can be
found rather easily long before the end of the original packet of data.

	Thanks to the people listed below who variously suggested that:

	a) I might be using SOCK_DGRAM sockets (which are unreliable
	especially for large blocks of data) instead of SOCK_STREAM

	b) I wasn't checking the return value on read() (or write())

	c) the two machines involved had differently sized TCP-send/rec
	buffer spaces

From:
Scott Townsend	fsset@bach.lerc.nasa.gov
Stuart Levy	slevy@geom.umn.edu
Mahlon Stacy	mcs@mayo.edu
Ray Niblett 	niblett@sgi.com             
Mike Sweet	mike@BRL.MIL

Also, find below a longer description of c) from Ray Niblett at SGI and
a handy piece of reference code, mread(), from Mike Sweet at BRL.MIL.

Regards,
                             __          __
Loki Jorgenson              / /          \ \  node:  loki@Physics.McGill.CA
Grad, Systems Manager      / //////  \\\\\\ \ BITNET: PY29@MCGILLA
Physics, McGill University \ \\\\\\  ////// / fax:   (514) 398-8434
Montreal Quebec CANADA      \_\          /_/  phone: (514) 398-7027

-------------------------------------------------------------------------
KERNEL Differences:

You might take a look at the parameters in the file: 

  /usr/sysgen/master.d/bsd

these are kernel configuration parameters for networking operations.
They are documented in the Network Communications Guide section 8.8.

tcp_sendspace and tcp_recvspace parameters determine the default
amount of buffer space used by TCP.  I have seen different values
used on different releases of the operating system (each release
getting larger).  However, I am not sure if the user of the machine        
changed the value or if I was looking at default values.  If you
change a parameter you will have to boot a new kernel.

Also, calls to setsockopt using SO_SNDBUF and SO_RCVBUF can modify
the buffer size from within a program.

------------------------------------------------------------------
/*
 *			M R E A D
 *
 * This function performs the function of a read(II) but will
 * call read(II) multiple times in order to get the requested
 * number of characters.  This can be necessary because pipes
 * and network connections don't deliver data with the same
 * grouping as it is written with.
 */
static int
mread(fd, bufp, n)
int fd;
register char	*bufp;
unsigned	n;
{
	register unsigned	count = 0;
	register int		nread;

	do {
		nread = read(fd, bufp, n-count);
		if(nread == -1)
			return(nread);
		if(nread == 0)
			return((int)count);
		count += (unsigned)nread;
		bufp += nread;
	 } while(count < n);

	return((int)count);
}
                             __          __
Loki Jorgenson              / /          \ \  node:  loki@Physics.McGill.CA
Grad, Systems Manager      / //////  \\\\\\ \ BITNET: PY29@MCGILLA
Physics, McGill University \ \\\\\\  ////// / fax:   (514) 398-8434
Montreal Quebec CANADA      \_\          /_/  phone: (514) 398-7027