socket connection dropping characters

Chris Torek chris at mimsy.umd.edu
Sat Apr 14 04:03:09 AEST 1990


In article <2125 at nosc.NOSC.MIL> putnam at peanuts.nosc.mil (Mike Putnam) writes:
>... opens a stream socket ... the server begins to drop characters.

Stream sockets are supposed to be reliable.  If the connection loses
characters, there is a bug in the stream socket code.  I suspect that
is not the problem, however:

>      to.tv_sec = 5;
>      if (select (sock + 1, &ready,0, 0, &to) < 0) {

(you should set to.tv_usec, and you should cast the two `0's, but this is
not the problem I see...)

(after msgsock comes back from accept)

>	  do {   
>            bzero(buf, sizeof(buf));
>            if ((rval = read(msgsock, buf, sizeof(buf))) <0)
>               perror("reading stream message");
>            else if (rval == 0)   
>               printf("ending connection\n");
>            else
>               printf ("-->%s\n",buf);
>              /* write(msgsock,OK,sizeof(OK));*/
>         } while (rval > 0);

The `printf' call is inappropriate.  If rval < sizeof(buf), we can be
sure that buf[rval] is '\0', so that the `string' is terminated and
printf() will not go chasing phantoms.  But we could have rval ==
sizeof(buf), in which case we know nothing about buf[rval] other than
that accessing this location is illegal.

Also, it is worth noting that even if rval < sizeof(buf), it is possible
that buf[i]=='\0' for 0 <= i < rval, in which case the printf() will
stop copying at that point.


>Client
>*********************************
>   do {
>     if (write(sock, DATA, sizeof(DATA)) < 0) {
>        perror("writing on stream socket");
>        close (sock);
>     } 
>   } while (TRUE);

There may be no guarantee that write() will return sizeof(DATA): you
may be writing 1 <= n <= sizeof(DATA) bytes in some calls.  (4BSD TCP
stream sockets, except in non-blocking mode, will always return either
sizeof(DATA) or -1, except perhaps in the presence of signals.  This
is not necessarily true of other implementations.)  As with read()
loops, technically you need something like

	do {
		char *p = DATA;
		int n = sizeof DATA;
		while (n > 0) {
			int ret = write(sock, p, n);
			if (ret < 0) {
				perror("write");
				close(sock);
				sock = -1;
				break;
			}
			if (ret == 0)
				panic("ret == 0");
			p += ret;
			n -= ret;
		}
	} while (sock >= 0);
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.questions mailing list