12

因此,我尝试使用的非常简单的代码在这里: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

4 回答 4

18

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

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。

于 2013-03-31T20:36:06.717 回答
6

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

我有一个非常相似的问题发生在我身上。我意识到您已经解决了这个问题,但是我认为分享我如何为我解决这个问题会很好。

我发现的问题与我的防火墙设置有关。我发现数据包被 Windows 防火墙阻止了。

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

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

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

于 2016-03-23T18:16:10.773 回答
0

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

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

于 2013-06-26T08:43:04.827 回答
-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
于 2016-02-18T13:54:07.903 回答