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.connect((hostname, PORT))<br />

s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO)<br />

try:<br />

» s.send('#' * 65000)<br />

except socket.error:<br />

» print 'The message did not make it'<br />

» option = getattr(IN, 'IP_MTU', 14) # constant taken from <br />

» print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option)<br />

else:<br />

» print 'The big message was sent! Your network supports really big packets!'<br />

If we run this program against a server elsewhere on my home network, then we discover that my<br />

wireless network allows physical packets that are no bigger than the 1,500 bytes typically supported by<br />

Ethernet-style networks:<br />

$ python big_sender.py guinness<br />

The message did not make it<br />

MTU: 1500<br />

It is slightly more surprising that the loopback interface on my laptop, which presumably could<br />

support packets as large as my RAM, also imposes an MTU that is far short <strong>of</strong> the maximum UDP packet<br />

length:<br />

$ python big_sender.py localhost<br />

The message did not make it<br />

MTU: 16436<br />

But, the ability to check the MTU is a fairly obscure feature. As you can see from the program listing,<br />

<strong>Python</strong> 2.6.5 on my machine for some reason fails to include the IP_MTU socket option name that is<br />

necessary to determine a socket’s current MTU, so I had to manually copy the integer option code 14 out<br />

<strong>of</strong> one <strong>of</strong> the system C header files. So you should probably ignore the issue <strong>of</strong> fragmentation and, if you<br />

worry about it at all, try to keep your UDP packets short; but this example was at least useful in showing<br />

you that fragmentation does need to take place, in case you run into any <strong>of</strong> its consequences!<br />

Socket Options<br />

The POSIX socket interface also supports all sorts <strong>of</strong> socket options that control specific behaviors <strong>of</strong><br />

network sockets. These are accessed through the <strong>Python</strong> socket methods getsockopt() and setsockopt(),<br />

using the options you will find documented for your operating system. On Linux, for example, try viewing<br />

the manual pages socket(7), udp(7), and—when you progress to the next chapter—tcp(7).<br />

When setting socket options, you have to first name the “option group” in which they live, and then<br />

as a subsequent argument name the actual option you want to set; consult your operating system<br />

manual for the names <strong>of</strong> these groups. See Listing 2–3 in the next section for some example real-world<br />

calls involving socket options. Just like the <strong>Python</strong> calls getattr() and setattr(), the set call simply<br />

takes one more argument:<br />

value = s.getsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST)<br />

s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, value)<br />

Many options are specific to particular operating systems, and may be finicky about how their<br />

options are presented. Here are some <strong>of</strong> the more common:<br />

• SO_BROADCAST: Allows broadcast UDP packets to be sent and received; see the next<br />

section for details.<br />

31

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

Saved successfully!

Ooh no, something went wrong!