树莓派无法接收组播包
我刚开始学习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”接收到数据,但树莓派还是无法接收。
编辑:结果发现我在工作时把一个脚本留在了控制台窗口里。不过,它还是没有接收到任何东西。
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 个回答
太好了!看起来问题出在我的Sky路由器上!
看起来对提问者的问题的回答是肯定的。是的,确实很糟糕。
:(
不知道接下来该怎么办...