树莓派无法接收组播包

1 投票
1 回答
3079 浏览
提问于 2025-04-17 21:01

我刚开始学习Python编程和Linux/Raspbian,最近遇到了一个非常棘手的问题,已经折腾了好几个星期。我一直在努力解决,但经过几晚熬夜到凌晨1点,还是没搞定,所以我决定寻求帮助。

我有一台树莓派,设置用来接收来自一个叫做“owl intuition”的设备的数据(这是一个电力和光伏监测器),它通过224.192.32.19这个地址和22600这个端口发送数据。

我在使用iptables和fail2ban,但我设置了一条规则,允许所有的多播流量,而且源IP地址不在fail2ban的黑名单上。

iptables的规则如下:

目标 协议 选项 输入 输出 源地址 目标地址
接受 所有 -- 任意 任意 任何地方 任何地方 PKTTYPE = multicast

我在用一些非常简单的Python脚本尝试接收数据包,但一直没有成功。

我用同样的脚本尝试接收来自239.255.255.250:1900的数据包,结果很好。

我还在一台Windows机器上尝试过“mcsend 224.192.32.19 22600”,可以用“rtpqual 224.192.32.19 22600”接收到数据,但树莓派还是无法接收。

奇怪的是,当我运行“netstat -g”时,虽然我没有运行任何监听程序,却得到了以下信息...

编辑:结果发现我在工作时把一个脚本留在了控制台窗口里。不过,它还是没有接收到任何东西。

IPv6/IPv4组成员信息
接口 引用计数 组


lo 1 all-systems.mcast.net
eth0 1 224.192.32.19
eth0 1 all-systems.mcast.net

另外,如果我运行“ifconfig eth0”,我得到:

eth0 链路封装:以太网 硬件地址 b8:27:eb:4c:46:71
inet 地址:192.168.0.20 广播:192.168.0.255 子网掩码:255.255.255.0
启用 广播 运行中 多播 MTU:1500 指标:1
接收数据包:27645 错误:0 丢弃:0 超限:0 帧:0
发送数据包:11846 错误:0 丢弃:0 超限:0 载波:0
碰撞:0 发送队列长度:1000
接收字节:1701082 (1.6 MiB) 发送字节:2027974 (1.9 MiB)

所以我可以安全地假设树莓派支持/启用了多播。

Python脚本如下(默认的IP地址/端口不工作,'帮助'中的IP地址/端口可以工作):

from socket import socket, inet_aton, IPPROTO_IP, IP_ADD_MEMBERSHIP
from socket import AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_REUSEADDR, INADDR_ANY
from optparse import OptionParser
import struct

parser = OptionParser()
parser.add_option("-g", "--group", dest="group", default="224.192.32.19", help="IP Multicast Group (default: 239.255.255.250)")
parser.add_option("-p", "--port", dest="port", default=22600, help="IP Multicast UDP port number (default: 1900)")
parser.add_option("-b", "--buffer", dest="buffer", default=1500, help="IP Socket buffer size (default: 1500 bytes)")
options, args = parser.parse_args()

MCAST_GRP   = options.group
MCAST_PORT  = options.port
BUFFER_SIZE = options.buffer

sock = socket(AF_INET, SOCK_DGRAM)
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
mreq = struct.pack('=4sl', inet_aton(MCAST_GRP), INADDR_ANY) # pack MCAST_GRP correctly
sock.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)         # Request MCAST_GRP

sock.bind((MCAST_GRP, MCAST_PORT))                           # Bind to all intfs

while True:
    data, srv_sock = sock.recvfrom(BUFFER_SIZE)              # Receive data (blocking)
    srv_addr, srv_srcport = srv_sock[0], srv_sock[1]
    print "%s sent: %s" % (srv_addr, data)

我搞不清楚问题出在哪里:

  • 树莓派,可能是iptables的规则
  • 网络(路由器可能不支持这些IP地址/端口的多播 - 网络计算机未接收到多播
  • 树莓派上可能有其他东西在订阅这个IP地址,从而阻止了我的Python脚本

感谢大家的帮助,这真让我头疼。

拉塞尔。

1 个回答

0

太好了!看起来问题出在我的Sky路由器上!

http://helpforum.sky.com/t5/Broadband-Setup-Connection-WiFi/Sky-Hub-Is-it-really-bad/m-p/1845916#M48979

看起来对提问者的问题的回答是肯定的。是的,确实很糟糕。

:(

不知道接下来该怎么办...

撰写回答