
ii
6.4 TCP Socket Life Cycle
93
call send() once, with size parameter n, than it is to call it n times with size parameter 1. 2
However, if you call send() with a size parameter that is much larger than SQS, the system
has to transfer the data from the user address space in SQS-sized chunks. That is, the socket
layer fills up the SendQ buffer, waits for data to be transferred out of it by the TCP protocol,
refills SendQ, waits some more, and so on. Each time the sockets layer has to wait for data to
be removed from SendQ, some time is wasted in the form of overhead (i.e., a context switch
occurs). This overhead is approximately the same as that incurred by a completely new system
call. Thus, the
effective
size of a call to send () is limited by the actual SQS. For receive, the same
principle applies: However large the buffer you give to recv(), it will be copied out in chunks
no larger than RQS, with overhead incurred between chunks.
If you are writing a program for which throughput is an important performance metric,
you will probably want to change the send and receive buffer sizes using the SO_RCVBUF and
SO_SNDBUF socket options. Although there is always a system-imposed maximum size for
each buffer, it is typically significantly larger than the default on modern systems. Remember
that these considerations apply only if your program needs to send an amount of data
significantly larger than the buffer size all at once.
6.4 TCP Socket Life Cycle
The sockets interface permits send() and recv() on a TCP socket only when it is in the
connected or "Established" state, that is, only when it has completed the opening handshake
message exchange required to establish a TCP connection. Let us now consider how a socket
gets to and from the Established state; as we'll see in Section 6.4.2, these details affect the
definition of reliability and the behavior of bind(). In what follows, as in all the examples of
this book, we assume that connect() is called by the client and that the server calls bind(),
listen(), and accept ().
6.4.1 Connecting
The relationship between the connect() call and the protocol events associated with connec-
tion establishment at the client is illustrated in Figure 6.6. In this and the remaining figures of
this section, the large arrows depict events that cause the socket structures to change state.
Events that occur in the application program (i.e., function calls and returns) are shown in the
upper part of the figure; events such as message arrivals are shown in the lower part of the
figure. Time proceeds left to right in these figures. The client's Internet address is depicted as
A.B.C.D, and the server's is W.X.Y.Z; the server's port number is Q.
2 The same thing generally applies to recv(), although calling recv() with a larger buffer size parameter
does not guarantee that more data will be returned (unless you change the socket semantics--compare
the MSG_WAITALL flag).