the server distinguishes the segments from the different clients using source IP
addresses and source port numbers.
Figure 3.5 shows a Web server that spawns a new process for each connection.
As shown in Figure 3.5, each of these processes has its own connection socket
through which HTTP requests arrive and HTTP responses are sent. We mention,
however, that there is not always a one-to-one correspondence between connection
sockets and processes. In fact, today’s high-performing Web servers often use only
one process, and create a new thread with a new connection socket for each new
client connection. (A thread can be viewed as a lightweight subprocess.) If you did
the first programming assignment in Chapter 2, you built a Web server that does just
this. For such a server, at any given time there may be many connection sockets
(with different identifiers) attached to the same process.
If the client and server are using persistent HTTP, then throughout the duration
of the persistent connection the client and server exchange HTTP messages via the
same server socket. However, if the client and server use non-persistent HTTP, then
a new TCP connection is created and closed for every request/response, and hence
a new socket is created and later closed for every request/response. This frequent
creating and closing of sockets can severely impact the performance of a busy Web
server (although a number of operating system tricks can be used to mitigate
the problem). Readers interested in the operating system issues surrounding persistent and non-persistent HTTP are encouraged to see [Nielsen 1997; Nahum
2002].
Now that we’ve discussed transport-layer multiplexing and demultiplexing,
let’s move on and discuss one of the Internet’s transport protocols, UDP. In the next
section we’ll see that UDP adds little more to the network-layer protocol than a multiplexing/demultiplexing service.