[comp.unix.wizards] socket problem?

briand@rfengr.com (Brian Dear) (05/21/91)

Question about sockets.  I've got a simple server program that runs in the
background.  It sits in an infinite loop, with an accept() call, waiting
for a client's request.  And a request comes in, it executes a read(). 
The read() function reads a single char; with that char I know what type of
request the client's making.  If the single char is 'r', for instance, 
the server sends out a write() of a struct 10000 or so bytes long. 
That all works fine.

It's the client side that's got a bug.  It sets up its socket with
the server successfully, connect()'s successfully, etc.  Sends out 
its 'r' successfully (cuz the server gets it and sends out its struct)
but the client's read() never works.  The client has a read() function
such as this

	read( sd, &theStruct, sizeof(theStruct) );

where sd is the socket descriptor and theStruct is just some big structure.
Read returns a value of 3 or it just blocks altogether.  Any ideas?

Please direct any replies to "brian@coconut.com" -- Thanks!

Brian Dear     Coconut Computing, Inc.    brian@coconut.com

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (05/21/91)

In article <1991May20.210923.12177@rfengr.com> brian@coconut.com writes:
>
>Question about sockets.  I've got a simple server program that runs in the
>background.  It sits in an infinite loop, with an accept() call, waiting

>It's the client side that's got a bug.  It sets up its socket with
>the server successfully, connect()'s successfully, etc.  Sends out 
>its 'r' successfully (cuz the server gets it and sends out its struct)
>but the client's read() never works.  The client has a read() function
>such as this
>
>	read( sd, &theStruct, sizeof(theStruct) );
>
>where sd is the socket descriptor and theStruct is just some big structure.
>Read returns a value of 3 or it just blocks altogether.  Any ideas?

This is not a "bug", but rather a documented feature of sockets. reads and
writes are not guaranteed to transfer exactly the amount of data that you
request to be sent. Therefore, in doing I/O on sockets, its safer to make
sread() and swrite() functions that read until either all the requested
data is read/written, or -1 or 0 is returned. Here's what I use:

int sread(int s, char *buf, int n)
{
	int save = n;
	int tmp; /* number of chars read this call */
	while (n) {
		if ((tmp = read(s, buf, n)) <= 0)
			return tmp ? tmp : save-n; 
		n -= tmp; buf += tmp;
    }
    return save;
}

swrite() is exactly the same thing, replace the read(...) with write(...);

		-Kartik

--
internet% ypwhich

subbarao@phoenix.Princeton.EDU -| Internet
kartik@silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO@PUCC.BITNET			          - Bitnet

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (05/24/91)

In article <1991May20.210923.12177@rfengr.com>, briand@rfengr.com (Brian Dear) writes:

> Question about sockets.  I've got a simple server program [...].
> That all works fine.

> It's the client side that's got a bug.  It sets up its socket with
> the server successfully, connect()'s successfully, etc.  Sends out
> its 'r' successfully (cuz the server gets it and sends out its
> struct) but the client's read() never works.  The client has a read()
> function such as this

> 	read( sd, &theStruct, sizeof(theStruct) );

Danger, danger.  read() on a socket - indeed, I think on anything but a
plain file - does not necessarily read as many bytes as asked for.  It
can read anywhere from one byte to the full amount (even zero bytes,
but only if the socket is marked non-blocking or if the other end has
been shut down).

You have to keep calling read until you get an error, EOF, or
everything you're looking for.  Something like

int Read(fd,buf,nb)
int fd;
char *buf;
int nb;
{
 int left;
 char *bp;
 int nr;

 left = nb;
 bp = buf;
 while (left > 0)
  { nr = read(fd,bp,left);
    if (nr < 0) return(-1);
    if (nr == 0) return(nb-left);
    left -= nr;
    bp += nr;
  }
 return(nb);
}

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

rbj@uunet.uu.net (Root Boy Jim) (05/30/91)

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) writes:
?In article <1991May20.210923.12177@rfengr.com> brian@coconut.com writes:
?>
?>	read( sd, &theStruct, sizeof(theStruct) );
?>
?>where sd is the socket descriptor and theStruct is just some big structure.
?>Read returns a value of 3 or it just blocks altogether.  Any ideas?
?
?This is not a "bug", but rather a documented feature of sockets...

I know. But why a value of `3'? Often on the first read.
I have seen this exact behavior. What is special about `3'?
-- 
		[rbj@uunet 1] stty sane
		unknown mode: sane