Foundations of Python Network Programming

(WallPaper) #1
Chapter 7 ■ Server arChiteCture

117

A Simple Protocol


To keep your attention on the various options presented by server design, the examples in this chapter feature a
minimalist TCP protocol where the client asks one of three plain-text ASCII questions and then waits for the server to
complete its answer. As in HTTP, the client may ask as many questions as it wants while the socket remains open and
then close the connection without any warning when it has no more questions. The end of each question is delimited
with the ASCII question mark character.


Beautiful is better than?


The answer is then sent back delimited by a period.

Ugly.


Each of the three question-and-answer pairs is based on one of the aphorisms of the Zen of Python, a poem
about the inner consistent design of the Python language. Run Python and type import this any time that you need
inspiration and want to reread the poem.
To build a client and several servers around this protocol, a number of routines are defined in Listing 7-1, which
you will note has no command-line interface of its own. The module exists solely to be imported as a support module
by the subsequent listings so that they can reuse its patterns without having to repeat them.


Listing 7-1. Data and Routines to Support the Toy Zen-of-Python Protocol


#!/usr/bin/env python3


Foundations of Python Network Programming, Third Edition


https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter07/zen_utils.py


Constants and routines for supporting a certain network conversation.


import argparse, socket, time


aphorisms = {b'Beautiful is better than?': b'Ugly.',
b'Explicit is better than?': b'Implicit.',
b'Simple is better than?': b'Complex.'}


def get_answer(aphorism):
"""Return the string response to a particular Zen-of-Python aphorism."""
time.sleep(0.0) # increase to simulate an expensive operation
return aphorisms.get(aphorism, b'Error: unknown aphorism.')


def parse_command_line(description):
"""Parse command line and return a socket address."""
parser = argparse.ArgumentParser(description=description)
parser.add_argument('host', help='IP or hostname')
parser.add_argument('-p', metavar='port', type=int, default=1060,
help='TCP port (default 1060)')
args = parser.parse_args()
address = (args.host, args.p)
return address

Free download pdf