Commonly Asked Socket Questions (Was: non-blocking sockets)

Chris Torek chris at mimsy.umd.edu
Sat Apr 14 04:22:38 AEST 1990


In article <412 at servio.UUCP> penneyj at servio.UUCP (D. Jason Penney) writes:
[lots of correct stuff...]

>>Will the receiving end [of a stream socket] receive all 512*512 bytes
>>before returning?

>Emphatically not!  Supposing that ethernet is actually being used, the
>underlying packet size is something like 2K bytes.

(well, 1.5K)

>Since sockets are STREAMS (record boundaries are not preserved),

Not all sockets are streams.  Some are `datagram sockets'; these do
preserve record boundaries.  Such sockets generally will refuse to
transmit 512*512 bytes as a single record, however.

In addition, many implementations provide only two services: reliable
(flow controlled, error checked, sequenced, clean) `streams' and
unreliable (uncontrolled, passes errors on, loses, duplicates,
reorders, and generally mucks up data at times) `datagrams'.  There
*are* such things as reliable datagram sockets; they are merely
relatively rare in current implementations.

[more correct-stuff deleted]

>>What is the optimal size to send using socket?

>My personal preference is to attempt to send as many bytes as possible in each
>call to write().

This is generally the best approach for stream sockets, since the
implementation can break up large messages as appropriate for the media
in use (media, not medium, as there may be more than one).  Datagram
sockets are an exception, again.

In any case, there is no single optimal size.  On BSD VAXen over local
Ethernets, 1K (and multiples thereof) works particularly well, but on
the same machines over slow serial lines smaller packets may work out
better.  This is why it is generally best to let the implementation
break up large writes.  (But see below.)

>It is probably not relevant, but we have noticed on most of our Unix
>hosts that both most streams seem to buffer 8K bytes of incoming and
>another 8K bytes of outgoing data.

On BSD boxes and systems with TCPs derived therefrom, TCP stream sockets
have `tcp_sendspace' and `tcp_recvspace' of kernel buffering for outgoin
and incoming data respectively.  Newer systems allow socket options to
change the buffer sizes.  These default to 4K or 8K bytes, typically.

Since the outgoing data must be retained until the remote host has
acknowledged correct reception (in case the data are lost or mangled on
the way and must be re-sent), and since the buffer has a limited size,
writes of more than tcp_sendspace will cause the writer to `hang'
(block or wait) by default until the first data have been acknowledged
and the rest have been buffered up.  Thus, the `most efficient' size
for a write() call is `tcp_sendspace - however_much_is_still_waiting',
at least in one sense.

This is where non-blocking write()s can be useful: after setting FIONBIO
mode, a write() of `too many' bytes will place as many in the outgoing
buffer as will fit, and will return the count of bytes placed in that buffer.
This could be anything between 0 and the number of bytes given to write().
Refer to the parent article of this one to see how to manage non-blocking
writes.
-- 
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