On Jun 24, 2009, at 05:11 , Johan Tibell wrote:
Oleg writes:
> In this design, the operation of creating a socket and connecting it
> are bundled together -- which is very common and is the case for
> System V, I think (where it is called openActive, I think). If you for
I don't believe that is specced by SVID or successors. TLI/XTI may have had something similar to it but nobody wants to go there. :)
> some reason want to keep 'socket' and 'connect' separate, then
One reason to do so is that for connectionless (UDP) sockets, the BSD socket protocol *allows* connect(); this allows you to use send() instead of sendto() and is an optimization for the case where you are communicating with a single remote service. (That said, the only program/service I can think of where this is guaranteed is tftp. There's no point in optimizing cases where it might be true on a case-by-case basis, such as DNS when only a single nameserver has been specified.)
A more common case is that servers accept() instead of connect(). listen() switches the socket to this state. (NB! bind() is *not* involved here; a client can bind(), although it's unusual, and a server may register with a naming service instead of bind()ing to a well known port — see Sun RPC for example.)
Still another state change is invoked by shutdown(), which can make read/recv and/or write/send illegal operations. A socket which has been shutdown() for both send and receive can be close()d or select()ed; the latter lets you wait for the other end to disconnect, or to catch late errors.
The BSD socket protocol is explicitly driven by a state machine, btw, but it's a fairly complex one. Also, it's generally described in terms of the kernel's view, which includes states you normally can't distinguish in a user program (for example, a socket in TIME_WAIT keeps its port unavailable unless you use SO_REUSEADDR, but is otherwise indistinguishable from a socket which has been close()d and reaped).