Recipe13.1.Passing Messages with Socket Datagrams


Recipe 13.1. Passing Messages with Socket Datagrams

Credit: Jeff Bauer

Problem

You want to communicate small messages between machines on a network in a lightweight fashion, without needing absolute assurance of reliability.

Solution

This task is just what the UDP protocol is for, and Python makes it easy for you to access UDP via datagram sockets. You can write a UDP server script (server.py) as follows:

import socket port = 8081 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Accept UDP datagrams, on the given port, from any sender s.bind(("", port)) print "waiting on port:", port while True:     # Receive up to 1,024 bytes in a datagram     data, addr = s.recvfrom(1024)     print "Received:", data, "from", addr

You can write a corresponding UDP client script (client.py) as follows:

import socket port = 8081 host = "localhost" s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto("Holy Guido! It's working.", (host, port))

Discussion

Sending short text messages with socket datagrams is simple to implement and provides a lightweight message-passing idiom. Socket datagrams should not be used, however, when reliable delivery of data must be guaranteed. If the server isn't available, your message is lost. However, in many situations, you won't care whether the message gets lost, or, at least, you do not want to abort a program just because a message can't be delivered.

Note that the sender of a UDP datagram (the "client" in this example) does not bind the socket before calling the sendto method. On the other hand, to receive UDP datagrams, the socket does have to be bound before calling the recvfrom method.

Don't use this recipe's simple code to send large datagram messages, especially under Windows, which may not respect the buffer limit. To send larger messages, you may want to do something like this:

BUFSIZE = 1024 while msg:     bytes_sent = s.sendto(msg[:BUFSIZE], (host, port))     msg = msg[bytes_sent:]

The sendto method returns the number of bytes it has actually managed to send, so each time, you retry from the point where you left off, while ensuring that no more than BUFSIZE octets are sent in each datagram.

Note that with datagrams (UDP) you have no guarantee that all (or any) of the pieces that you send as separate datagrams arrive to the destination, nor that the pieces that do arrive are in the same order in which they were sent. If you need to worry about any of these reliability issues, you may be better off with a TCP connection, which gives you all of these assurances and handles many delicate behind-the-scenes aspects nicely on your behalf. Still, I often use socket datagrams for debugging, especially (but not exclusively) where an application spans more than one machine on the same, reliable local area network. The Python Standard Library's logging module also supports optional use of UDP for its logging output.

See Also

Recipe 13.11 for a typical, useful application of UDP datagrams in network operations; documentation for the standard library modules socket and logging in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net