Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!mcnc!uvaarpa!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.unix.questions Subject: Re: Commonly Asked Socket Questions (Was: non-blocking sockets) Keywords: Sockets,Non-Blocking,Asynchronous,Streams Message-ID: <23715@mimsy.umd.edu> Date: 13 Apr 90 18:22:38 GMT References: <28080@ut-emx.UUCP> <412@servio.UUCP> Distribution: usa Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 69 In article <412@servio.UUCP> penneyj@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@cs.umd.edu Path: uunet!mimsy!chris