[comp.unix.wizards] preserving message boundaries

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."