Credit: Jeff Bauer
You need to communicate small messages between machines on a TCP/IP network in a lightweight fashion, without needing absolute assurance of reliability.
This is what the UDP protocol is for, and Python makes it
easy for you to access it, via datagram sockets. You can write a server
(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 1: # Receive up to 1,024 bytes in a datagram data, addr = s.recvfrom(1024) print "Received:", data, "from", addr
And you can write a client (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))
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, there are many situations in which you won’t care whether the message gets lost, or, at least, you won’t want to abort a program just because the message can’t be delivered.
Note that the sender of a UDP datagram (the client in this example)
does not need to bind the socket before calling the
sendto
method. On the other hand, to receive UDP
datagrams, the socket does need to be bound before calling the
recvfrom
method.
Don’t use this recipe’s simple code to send very large datagram messages, especially under Windows, which may not respect the buffer limit. To send larger messages, you will probably 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 none 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 that 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 the application spans more than one machine on the same, reliable local area network.
Recipe 10.13 for a typical, useful application
of UDP datagrams in network operations; documentation for the
standard library module socket
in the
Library Reference.