1280 Chapter 61
In both of these scenarios, the outstanding TCP endpoint is unable to accept new
connections. Nevertheless, in both cases, by default, most TCP implementations
prevent a new listening socket from being bound to the server’s well-known port.
The EADDRINUSE error doesn’t usually occur with clients, since they typically use an
ephemeral port that won’t be one of those ports currently in the TIME_WAIT
state. However, if a client binds to a specific port number, then it also can
encounter this error.
To understand the operation of the SO_REUSEADDR socket option, it can help to return
to our earlier telephone analogy for stream sockets (Section 56.5). Like a telephone
call (we ignore the notion of conference calls), a TCP socket connection is identifiable
by the combination of a pair of connected endpoints. The operation of accept() is
analogous to the task performed by a telephone operator on an internal company
switchboard (“a server”). When an external telephone call arrives, the operator
transfers it to some internal telephone (“a new socket”) within the organization.
From an outside perspective, there is no way of identifying that internal telephone.
When multiple external calls are being handled by the switchboard, the only way of
distinguishing them is via the combination of the external caller’s number and the
switchboard number. (The latter is necessary when we consider that there will be
multiple company switchboards within the telephone network as a whole.) Analo-
gously, each time we accept a socket connection on a listening socket, a new socket
is created. All of these sockets are associated with the same local address as the
listening socket. The only way of distinguishing them is via their connections to
different peer sockets.
In other words, a connected TCP socket is identified by a 4-tuple (i.e., a combi-
nation of four values) of the following form:
{ local-IP-address, local-port, foreign-IP-address, foreign-port }
The TCP specification requires that each such tuple be unique; that is, only one
corresponding connection incarnation (“telephone call”) can exist. The problem is
that most implementations (including Linux) enforce a stricter constraint: a local
port can’t be reused (i.e., specified in a call to bind()) if any TCP connection incar-
nation with a matching local port exists on the host. This rule is enforced even
when the TCP could not accept new connections, as in the scenarios described at
the start of this section.
Enabling the SO_REUSEADDR socket option relaxes this constraint, bringing it
closer to the TCP requirement. By default, this option has the value 0, meaning
that it is disabled. We enable the option by giving it a nonzero value before binding
a socket, as shown in Listing 61-4.
Setting the SO_REUSEADDR option means that we can bind a socket to a local port
even if another TCP is bound to the same port in either of the scenarios described
at the start of this section. Most TCP servers should enable this option. We have
already seen some examples of the use of this option in Listing 59-6 (page 1221)
and Listing 59-9 (page 1228).