Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!ncar!tank!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.unix.questions Subject: Re: socket connection dropping characters Message-ID: <23714@mimsy.umd.edu> Date: 13 Apr 90 18:03:09 GMT References: <2125@nosc.NOSC.MIL> Distribution: usa Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 73 In article <2125@nosc.NOSC.MIL> putnam@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@cs.umd.edu Path: uunet!mimsy!chris