echo client and
server programs shown previously serve to illustrate socket
fundamentals. But the server model suffers from a fairly major flaw:
if multiple clients try to connect to the server, and it takes a long time
to process a given client’s request, the server will fail. More
accurately, if the cost of handling a given request prevents the
server from returning to the code that checks for new clients in a
timely manner, it won’t be able to keep up with all the requests, and
some clients will eventually be denied connections.
In real-world client/server programs, it’s far more typical to code a server so as to avoid blocking new requests while handling a current client’s request. Perhaps the easiest way to do so is to service each client’s request in parallel—in a new process, in a new thread, or by manually switching (multiplexing) between clients in an event loop. This isn’t a socket issue per se, and we already learned how to start processes and threads in Chapter 5. But since these schemes are so typical of socket server programming, let’s explore all three ways to handle client requests in parallel here.
The script in Example 13-4 works like the
echo server, but instead
forks a new process to handle each new client connection. Because
handleClient function runs in
a new process, the
function can immediately resume its main loop in order to detect and
service a new incoming request.
Example 13-4. PP3E\Internet\Sockets\fork-server.py ...