简单的 Python UDP 服务器:无法从本地主机以外的客户端接收数据包
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15734219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple Python UDP Server: trouble receiving packets from clients other than localhost
提问by Steve P.
So, the very simple code that I'm trying to use is here: http://wiki.python.org/moin/UdpCommunication
所以,我尝试使用的非常简单的代码在这里:http: //wiki.python.org/moin/UdpCommunication
(also here): Sending:
(也在这里): 发送:
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
Receiving:
接收:
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
The code works fine when I run both applications on my computer. I put the sending code on my laptop with:
当我在计算机上运行这两个应用程序时,代码运行良好。我把发送代码放在我的笔记本电脑上:
UDP_IP="IP address for my computer"
Everything else is the same. Yet, nothing happens. What am I doing incorrectly? I used wireshark and determined that the packet is being sent and received; however, the python program isn't receiving the packet. I'm very confused.
其他一切都是一样的。然而,什么也没有发生。我做错了什么?我使用了wireshark并确定正在发送和接收数据包;但是,python 程序没有收到数据包。我很困惑。
Any help is much appreciated. Thanks in advance.
任何帮助深表感谢。提前致谢。
采纳答案by Johannes Overmann
Try binding to all local interfaces on the receiving side:
尝试绑定到接收端的所有本地接口:
sock.bind(("", UDP_PORT)) # could also use "0.0.0.0"
Note that the behavior of operating systems is not entirely logical (nor consistent) in terms of binding when receiving UDP packets, especially for multicast traffic. This is the behavior you get:
请注意,在接收 UDP 数据包时,操作系统的行为在绑定方面并不完全合乎逻辑(也不一致),尤其是对于多播流量。这是你得到的行为:
Linux: Binding to a specific IP will filterthe incoming UDP packets and only the ones targeted at this specific IP will get through the filter. This means for example that multicast UDP packets received by an interface with IP 192.168.1.100 will notbe received when binding to IP 192.168.1.100. On Linux the normal bind does not bind to an interface. Use setsockopt(SO_BINDTODEVICE) for this. Binding to 0.0.0.0 (or "" on Python) will always receive all UDP packets received by the machine on all interfaces, regardless of the destination IP, so this is usually the most useful option on Linux.
Linux:绑定到特定 IP 将过滤传入的 UDP 数据包,只有针对此特定 IP 的数据包才能通过过滤器。这意味着,例如,当绑定到 IP 192.168.1.100 时,将不会收到由 IP 为 192.168.1.100 的接口接收的多播 UDP 数据包。在 Linux 上,普通绑定不会绑定到接口。为此使用setsockopt(SO_BINDTODEVICE)。绑定到 0.0.0.0(或 Python 上的“”)将始终接收机器在所有接口上收到的所有 UDP 数据包,而不管目标 IP,因此这通常是 Linux 上最有用的选项。
Windows: Binding to a specific IP will bind to the interface belonging to this IP, pretty much like setsockopt(SO_BINDTODEVICE) does on Linux. Incoming UDP packets are not filtered by this IP, so multicast traffic can be received even when binding to a concrete IP. (This is probably the first time the Windows behavior seems more consistent to me than the Linux behavior.)
Windows:绑定到特定 IP 将绑定到属于该 IP 的接口,与 Linux 上的 setsockopt(SO_BINDTODEVICE) 非常相似。传入的 UDP 数据包不会被此 IP 过滤,因此即使绑定到具体 IP,也可以接收多播流量。(这可能是第一次在我看来,Windows 的行为比 Linux 的行为更一致。)
Python does notabstract these OS specific differences away for sockets (as it does in other areas). As long as you have no explicit reason not to do so I suggest to always bind to 0.0.0.0.
Python 并没有将这些操作系统特定的差异抽象为套接字(就像在其他领域一样)。只要您没有明确的理由不这样做,我建议始终绑定到 0.0.0.0。
回答by Haridas N
Make sure that the server port is open while trying to execute recvfromcall. If the destination port from which the socket reading was down then we get this error.
尝试执行recvfrom调用时,请确保服务器端口已打开 。如果套接字读取的目标端口关闭,则会出现此错误。
I got the same error and fixed by reading this link - http://www.linuxsa.org.au/mailing-list/2001-04/668.html
我得到了同样的错误并通过阅读此链接修复 - http://www.linuxsa.org.au/mailing-list/2001-04/668.html
回答by Xvs
So if I want to send a message AND receive a response then how would the code look? Like this?
因此,如果我想发送消息并接收响应,那么代码看起来如何?像这样?
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
回答by Tom Myddeltyn
eventually figured out my issue and it was pretty complex and highly localized,
最终解决了我的问题,它非常复杂且高度本地化,
I had a very similar problem happen to me. I realize that you have already solved this problem, however I thought it would be good to share how I solved the issue for me.
我有一个非常相似的问题发生在我身上。我知道你已经解决了这个问题,但是我认为分享我如何为我解决这个问题会很好。
The issue I found was with my firewall settings. I found that the packets were being blocked by Windows Firewall.
我发现的问题是我的防火墙设置。我发现数据包被 Windows 防火墙阻止。
I too had used Wireshark which showed that packets were being sent and received. It is important to note that Wireshark grabs packets at a much lower level than a Python application.
我也使用过 Wireshark,它显示正在发送和接收数据包。值得注意的是,Wireshark 在比 Python 应用程序低得多的级别上抓取数据包。
By running my code locally with a listener on one port and a client on another port on the same PC, the firewall wasn't blocking the packets. When I moved to interfacing with an external machine, the firewall rules came into play blocking the incoming packets.
通过在同一台 PC 上的一个端口上使用侦听器和在另一个端口上的客户端在本地运行我的代码,防火墙没有阻止数据包。当我转向与外部机器接口时,防火墙规则开始发挥作用,阻止传入的数据包。
Changing the firewall policy fixed this issue. There are numerous ways and inherent security risks to changing the firewall to make this work so I will leave that part up to the IT professionals. :-)
更改防火墙策略解决了这个问题。更改防火墙以使其正常工作有多种方法和固有的安全风险,因此我将把这部分留给 IT 专业人员。:-)

