Chapter 7 ■ Server arChiteCture
120
for aphorism in random.sample(aphorisms, 3):
sock.sendall(aphorism)
print(aphorism, zen_utils.recv_until(sock, b'.'))
sock.close()
if name == 'main':
parser = argparse.ArgumentParser(description='Example client')
parser.add_argument('host', help='IP or hostname')
parser.add_argument('-e', action='store_true', help='cause an error')
parser.add_argument('-p', metavar='port', type=int, default=1060,
help='TCP port (default 1060)')
args = parser.parse_args()
address = (args.host, args.p)
client(address, args.e)
In the normal case, where cause_error is False, this client creates a TCP socket and transmits three aphorisms,
waiting after each one for the server to reply with an answer. But in case you want to see what any of the servers in
this chapter do in the case of an error, the -e option to this client will make it send an incomplete question and then
hang up abruptly on the server. Otherwise, you should see three questions with their answers if a server is up and
running correctly.
$ python client.py 127.0.0.1
b'Beautiful is better than?' b'Ugly.'
b'Simple is better than?' b'Complex.'
b'Explicit is better than?' b'Implicit.'
As with many other examples in this book, this client and the servers in this chapter use port 1060 but
accept a -p option that can specify an alternative if that port is not available on your system.
A Single-Threaded Server
The rich set of utilities provided in the zen_utils module of Listing 7-1 reduces the task of writing a simple
single-threaded server—the simplest possible design, which you saw already in Chapter 3—to only the three-line
function of Listing 7-3.
Listing 7-3. The Simplest Possible Server Is Single-Threaded
#!/usr/bin/env python3
Foundations of Python Network Programming, Third Edition
https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter07/srv_single.py
Single-threaded server that serves one client at a time; others must wait.
import zen_utils
if name == 'main':
address = zen_utils.parse_command_line('simple single-threaded server')
listener = zen_utils.create_srv_socket(address)
zen_utils.accept_connections_forever(listener)