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