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