09.11.2016 Views

Foundations of Python Network Programming 978-1-4302-3004-5

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 2 ■ UDP<br />

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)<br />

MAX = 65535<br />

PORT = 1060<br />

if sys.argv[1:] == ['server']:<br />

» s.bind(('127.0.0.1', PORT))<br />

» print 'Listening at', s.getsockname()<br />

» while True:<br />

» » data, address = s.recvfrom(MAX)<br />

» » print 'The client at', address, 'says', repr(data)<br />

» » s.sendto('Your data was %d bytes' % len(data), address)<br />

elif sys.argv[1:] == ['client']:<br />

» print 'Address before sending:', s.getsockname()<br />

» s.sendto('This is my message', ('127.0.0.1', PORT))<br />

» print 'Address after sending', s.getsockname()<br />

» data, address = s.recvfrom(MAX) # overly promiscuous - see text!<br />

» print 'The server', address, 'says', repr(data)<br />

else:<br />

» print >>sys.stderr, 'usage: udp_local.py server|client'<br />

You should be able to run this script right on your own computer, even if you are not currently in<br />

the range <strong>of</strong> a network, because both server and client use only the “localhost” IP address. Try running<br />

the server first:<br />

$ python udp_local.py server<br />

Listening at ('127.0.0.1', 1060)<br />

After printing this line <strong>of</strong> output, the server hangs and waits for an incoming message. In the source<br />

code, you can see that it took three steps for the server to get up and running.<br />

It first created a plain socket with the socket() call. This new socket has no name, is not yet<br />

connected to anything, and will raise an exception if you attempt any communications with it. But the<br />

socket is, at least, marked as being <strong>of</strong> a particular type: its family is AF_INET, the Internet family <strong>of</strong><br />

protocols, and it is <strong>of</strong> the SOCK_DGRAM datagram type, which means UDP. (The term “datagram” is the<br />

<strong>of</strong>ficial term for an application-level block <strong>of</strong> transmitted data. Some people call UDP packets<br />

“datagrams”—like Candygrams, I suppose, but with data in them instead.)<br />

Next, this simple server uses the bind() command to request a UDP network address, which you can<br />

see is a simple tuple containing an IP address (a hostname is also acceptable) and a UDP port number.<br />

At this point, an exception could be raised if another program is already using that UDP port and the<br />

server script cannot obtain it. Try running another copy <strong>of</strong> the server—you will see that it complains:<br />

$ python udp_local.py server<br />

Traceback (most recent call last):<br />

...<br />

socket.error: [Errno 98] Address already in use<br />

Of course, there is some very small chance that you got this error the first time you ran the server,<br />

because port 1060 was already in use on your machine. It happens that I found myself in a bit <strong>of</strong> a bind<br />

when choosing the port number for this first example. It had to be above 1023, <strong>of</strong> course, or you could<br />

not have run the script without being a system administrator—and, while I really do like my little<br />

example scripts, I really do not want to encourage anyone running them as the system administrator! I<br />

could have let the operating system choose the port number (as I did for the client, as we will see in a<br />

moment) and had the server print it out and then made you type it into the client as one <strong>of</strong> its<br />

20

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!