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:
这个任务就是UDP协议所处理的,而Python通过数据报套接字让你能更简单地访问UDP.你可以使用如下方式来写一个UDP服务器脚本(server.py):You can write a corresponding UDP client script (client.py) as follows:
同样,你可以使用如下方式写一个对于的UDP客户端脚本(client.py):2port = 8081
3host = "localhost"
4s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
5s.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.
注意一个UDP数据报的发送端(如这个例子中的"client")不需要在sendto 方法调用之前绑定套接字.另一方面,套接字需要在 recvfrom方法调用之前被绑定以接收UDP数据报.
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:
不要使用这个配方中的简单代码来发送大的数据报信息,特别是在Windows下,太大的数据可能超出的缓冲区大小的限制.你可能要使用如下方法来发送大量信息.
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.
sendto 方法返回实际上发送出去的字节数量,所以你每次从你剩下的数据起点开始重发,并且保证每个数据报发送的字节不大于BUFSIZE所指定的字节数.
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.
注意,数据报(UDP)不能保证你作为独立数据报发送的所有(或者说任意一个)片段到达目的地,也不能保证他们到达的的顺序和他们发送的顺序一样.如果你当心这些可靠性的问题,你最好使用TCP连接,它将给你这些保障,并在背后处理好很多幕后方面.不过,我经常使用套接字数据报来调试,特别是(但不限于)一个程序运行在同一个可靠的局域网中的多台机器时.Python标准库的logging模块也支持使用UDP来输出日志信息.
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.
食谱13.11给出一个在网络操作中典型的,可用的UDP数据报应用;标准库中socket和 logging模块的文档在库引用和Python in a Nutshell中可以找到