I l@ve RuBoard |
10.4 Passing Messages with Socket DatagramsCredit: Jeff Bauer 10.4.1 ProblemYou need to communicate small messages between machines on a TCP/IP network in a lightweight fashion, without needing absolute assurance of reliability. 10.4.2 SolutionThis 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)) 10.4.3 DiscussionSending 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. 10.4.4 See AlsoRecipe 10.13 for a typical, useful application of UDP datagrams in network operations; documentation for the standard library module socket in the Library Reference. |
I l@ve RuBoard |