简单的Python UDP服务器:从localhost以外的客户端接收数据包时遇到问题

时间:2013-03-31 20:32:42

标签: python

所以,我正在尝试使用的非常简单的代码是:http://wiki.python.org/moin/UdpCommunication

(也在这里): 发送:

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))

接收:

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

当我在计算机上运行这两个应用程序时,代码工作正常。我把发送代码放在笔记本电脑上:

UDP_IP="IP address for my computer"

其他一切都是一样的。然而,没有任何反应。我做错了什么?我使用wireshark并确定正在发送和接收数据包;但是,python程序没有收到数据包。我很困惑。

非常感谢任何帮助。 提前谢谢。

4 个答案:

答案 0 :(得分:15)

尝试绑定到接收端的所有本地接口:

sock.bind(("", UDP_PORT)) # could also use "0.0.0.0"

请注意,在接收UDP数据包时,操作系统的行为在绑定方面并不完全符合逻辑(也不一致),尤其是对于多播流量。这是你得到的行为:

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:绑定到特定IP将绑定到属于此IP的接口,非常类似于Linux上的setsockopt(SO_BINDTODEVICE)。传入的UDP数据包不会被此IP过滤,因此即使绑定到具体IP,也可以接收多播流量。 (这可能是Windows行为第一次看起来比Linux行为更加一致。)

Python 抽象这些操作系统特定的差异(就像在其他领域一样)。只要您没有明确的理由不这样做,我建议始终绑定到0.0.0.0。

答案 1 :(得分:4)

  

最终找出了我的问题,它非常复杂且高度本地化,

我遇到了一个非常类似的问题。我意识到你已经解决了这个问题,但我认为分享我如何为我解决这个问题会很好。

我发现的问题是我的防火墙设置。我发现Windows防火墙阻止了数据包。

我也使用过Wireshark,它显示正在发送和接收数据包。值得注意的是,Wireshark以比Python应用程序低得多的级别抓取数据包。

通过在一个端口上使用侦听器在本地运行我的代码,在同一台PC上的另一个端口上运行客户端,防火墙没有阻止数据包。当我转向与外部机器连接时,防火墙规则开始阻止传入的数据包。

更改防火墙策略解决了此问题。更改防火墙以使其工作有很多方法和固有的安全风险,因此我将把这部分留给IT专业人员。 : - )

答案 2 :(得分:0)

确保在尝试执行recvfrom调用时服务器端口处于打开状态。如果套接字读取的目标端口已关闭,那么我们会收到此错误。

我收到了相同的错误并通过阅读此链接修复了http://www.linuxsa.org.au/mailing-list/2001-04/668.html

答案 3 :(得分:-1)

因此,如果我想发送消息并收到响应,那么代码将如何显示?喜欢这个?

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