libes@cme.nbs.gov (Don Libes) (06/01/89)
There was some discussion earlier about preserving message boundaries, and I posted two functions that would do this (by encoding the length at the beginning). Namely: > sized_write(fd,buffer,nbytes) - just like write() > sized_read(fd,buffer,nbytes) - just like read() except that > it returns what was written > by one call to sized_write() I pointed out that I used them on top of TCP (although they work over anything). Someone wrote back that I should just be using send() and recv() as this is what they were intended to do. So I wrote a test program that loops, writing 2**n bytes, with n=n+1 each time through the loop. Another program reports what is being atomically read. Using sized_read(), it says: reading 1 chars reading 2 chars reading 4 chars reading 8 chars [everything looks hunky-dory here] reading 16 chars . . [obvious lines omitted] . reading 65536 chars reading 131072 chars reading 262144 chars ----------------------------------------------------------------------- Using recv() it says: reading 1 chars reading 2 chars reading 3072 chars <--- ????!?! reading 1020 chars <--- ????!?! reading 4096 chars <--- ????!?! reading 4096 chars reading 4096 chars reading 4096 chars . . [and so on] . --------------------------- recv() does not do atomic reads! Indeed, the man page says nothing about it. The man page for send() says something very cryptic about atomic writes - but even if it is atomic, it is worthless if recv() isn't. By the way, I am using SunOS 4.0.1. Should I report this to Sun? (It is not clear from the man pages that this is incorrect behavior.) Don Libes libes@cme.nbs.gov ...!uunet!cme-durer!libes
smb@ulysses.homer.nj.att.com (Steven M. Bellovin) (06/01/89)
TCP does not support record boundaries. Thus, the recv() call cannot preserve them, on any version of the UNIX system. Yes, I'm certain.
ed@mtxinu.COM (Ed Gould) (06/02/89)
>There was some discussion earlier about preserving message boundaries, >and I posted two functions that would do this (by encoding the length >at the beginning) ... >I pointed out that I used them on top of TCP (although they work over >anything). Someone wrote back that I should just be using send() and >recv() as this is what they were intended to do. >So I wrote a test program that [fails] >recv() does not do atomic reads! Indeed, the man page says nothing >about it. The man page for send() says something very cryptic about >atomic writes - but even if it is atomic, it is worthless if recv() >isn't. send()/recv() can do atomic things *only* if the underlying protocol supports them. TCP does not, so there is no way for recv() to know what was written by send(). If the underlying protocol were UDP, then send/recv would be atomic. As they would be, I presume, with a procotol like SPP/XNS. >By the way, I am using SunOS 4.0.1. Should I report this to Sun? (It >is not clear from the man pages that this is incorrect behavior.) This is not a bug, but a condition of the particular protocol (TCP). -- Ed Gould mt Xinu, 2560 Ninth St., Berkeley, CA 94710 USA ed@mtxinu.COM +1 415 644 0146 "I'll fight them as a woman, not a lady. I'll fight them as an engineer."