在Linux上使用python接收多播UDP数据报

我有一个硬件设备,在我的networking上发送多播数据。 我已经写了一个接收数据并打印它的Python脚本。 但是,我发现它只能在我的Windows XP电脑上运行,并且在我的Ubuntu Linux 10.04电脑上无法运行。 在Linux下,没有收到任何东西。 它只是围绕while循环,并没有收到任何数据。 我的代码张贴在下面。 你能看到任何理由,为什么这不会在Linux下工作? 谢谢,Rab。

# Multicast client # Adapted from: http://chaos.weblogs.us/archives/164 # on 05/03/2013 import socket ANY = "0.0.0.0" MCAST_ADDR = "224.0.33.154" MCAST_PORT = 31800 # Create a UDP socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # Allow multiple sockets to use the same PORT number sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # Bind to the port that we know will receive multicast data sock.bind((ANY,MCAST_PORT)) # Tell the kernel that we are a multicast socket sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) # Tell the kernel that we want to add ourselves to a multicast group # The address for the multicast group is the third param status = sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MCAST_ADDR) + socket.inet_aton(ANY)); # setblocking(0) is equiv to settimeout(0.0) which means we poll the socket. # But this will raise an error if recv() or send() can't immediately find or send data. sock.setblocking(0) while 1: try: data, addr = sock.recvfrom(1024) except socket.error as e: pass else: print "From: ", addr print "Data: ", data 

这里是我的Windows PC的一些示例输出:

 From: ('0.0.0.0', 31801) Data: EDCP 

请注意,远程硬件设备没有IP地址,正在使用地址0.0.0.0

编辑:我现在发现,这也不适用于我的Windows笔记本电脑。 所以,它看起来不是特定于操作系统的。 此外,我尝试运行另一个脚本来发送组播数据到相同的多播地址和端口。 我可以从一台电脑发送,所有其他人都可以使用我的接收脚本正确接收。 但是,只有我的一台Windows PC能够从有问题的硬件设备接收数据。 我想知道这是否是与以太网适配器或他们的configuration。 这可能是由于这个事实,硬件设备的IP地址为0.0.0.0,这些以太网适配器和/或我的接收器脚本需要告诉接收消息与这个地址? 在Linux PC上运行Wireshark可以看到来自硬件设备的数据。

Solutions Collecting From Web of "在Linux上使用python接收多播UDP数据报"

尝试绑定到多播组地址:

 sock.bind((MCAST_ADDR,MCAST_PORT)) 

另外,您不需要在接收器上设置多点传送TTL,这对发送者来说也是可选的。

我打了两天这个同样的问题。 Wireshark看到的数据包,但我的代码没有。 没有任何来自各种渠道的“确定”答案为我工作。 关键来自https://serverfault.com/questions/163244/linux-kernel-not-passing-through-multicast-udp-packets

运行“ip maddr”显示与您的代码相似的代码不是将多播地址添加到任何接口。 我强迫它被添加smcroute(见上面的链接)。 仍然没有喜乐。 数据包的源IP为172.22 …我的接口是172.17 …我向该NIC添加了172.22地址。 答对了! 现在我的代码收到了数据包。

现在如何让程序在没有smcroute的情况下工作? 我注释掉了setsockopt()调用。 仍然工作。 使用smcroute取消多播地址链接 – 失败。 取消注释setsockopt()调用,并用我的172.22地址替换“ANY”。 成功!

概要:

  1. 确保你有一个IP在同一个网段作为传入的数据包。
  2. 在IP_ADD_MEMBERSHIP调用中使用该地址,而不是INADDR_ANY。

如果你只有一个网卡,你可能不需要做2)。 我有三个,必须这样做。

万一它是密切的,我使用Ubuntu 12.04。 我不需要像其他人所描述的那样更改任何默认的/etc/sysctl.conf设置。 我试过了。 他们没有帮助,所以我重置他们回到安装默认值。