Foundations of Python Network Programming 978-1-4302-3004-5
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
CHAPTER 2 ■ UDP<br />
them anywhere in the world for many years. An up-to-date (and typically much more extensive) copy is<br />
also maintained online by the IANA at /www.iana.org/assignments/port-numbers.<br />
The foregoing discussion, as we will learn in Chapter 3, applies equally well to TCP<br />
communications, and, in fact, the IANA seems to consider the port-number range to be a single resource<br />
shared by both TCP and UDP. They never assign a given port number to one service under TCP but to<br />
another service under UDP, and, in fact, usually assign both the UDP and TCP port numbers to a given<br />
service even if it is very unlikely to ever use anything other than TCP.<br />
Sockets<br />
Enough explanation! It is time to show you source code.<br />
Rather than trying to invent its own API for doing networking, <strong>Python</strong> made an interesting decision:<br />
it simply provides a slightly object-based interface to all <strong>of</strong> the normal, gritty, low-level operating system<br />
calls that are normally used to accomplish networking tasks on POSIX-compliant operating systems.<br />
This might look like laziness, but it was actually brilliance, and for two different reasons! First, it is<br />
very rare for programming language designers, whose expertise lies in a different area, to create a true<br />
improvement over an existing networking API that—whatever its faults—was created by actual network<br />
programmers. Second, an attractive object-oriented interface works well until you need some odd<br />
combination <strong>of</strong> actions or options that was perfectly well-supported by grungy low-level operating<br />
system calls, but that seems frustratingly impossible through a prettier interface.<br />
In fact, this was one <strong>of</strong> the reasons that <strong>Python</strong> came as such a breath <strong>of</strong> fresh air to those <strong>of</strong> us<br />
toiling in lower-level languages in the early 1990s. Finally, a higher-level language had arrived that let us<br />
make low-level operating system calls when we needed them without insisting that we try going through<br />
an awkward but ostensibly “prettier” interface first!<br />
So, <strong>Python</strong> exposes the normal POSIX calls for raw UDP and TCP connections rather than trying to<br />
invent any <strong>of</strong> its own. And the normal POSIX networking calls operate around a central concept called a<br />
socket.<br />
If you have ever worked with POSIX before, you will probably have run across the fact that instead <strong>of</strong><br />
making you repeat a file name over and over again, the calls let you use the file name to create a “file<br />
descriptor” that represents a connection to the file, and through which you can access the file until you<br />
are done working with it.<br />
Sockets provide the same idea for the networking realm: when you ask for access to a line <strong>of</strong><br />
communication—like a UDP port, as we are about to see—you create one <strong>of</strong> these abstract “socket”<br />
objects and then ask for it to be bound to the port you want to use. If the binding is successful, then the<br />
socket “holds on to” that port number for you, and keeps it in your possession until such time as you<br />
“close” the socket to release its resources.<br />
In fact, sockets and file descriptors are not merely similar concepts; sockets actually are file<br />
descriptors, which happen to be connected to network sources <strong>of</strong> data rather than to data stored on a<br />
filesystem. This gives them some unusual abilities relative to normal files. But POSIX also lets you<br />
perform normal file operations on them like read() and write(), meaning that a program that just wants<br />
to read or write simple data can treat a socket as though it were a file without knowing the difference!<br />
What do sockets look like in operation? Take a look at Listing 2–1, which shows a simple server and<br />
client. You can see already that all sorts <strong>of</strong> operations are taking place that are drawn from the socket<br />
module in the <strong>Python</strong> Standard Library.<br />
Listing 2–1. UDP Server and Client on the Loopback Interface<br />
#!/usr/bin/env python<br />
# <strong>Foundations</strong> <strong>of</strong> <strong>Python</strong> <strong>Network</strong> <strong>Programming</strong> - Chapter 2 - udp_local.py<br />
# UDP client and server on localhost<br />
import socket, sys<br />
19