无法从另一设备接收UDP组播消息

3

我有一台Windows机器,在这台机器上我有两个脚本,它们通过UDP多播(在同一台机器上)发送和接收消息。我有一个C语言和Python3的实现。Python3的实现看起来像这样:

sender.py

import socket

MCAST_GRP = '239.1.1.1'
MCAST_PORT = 1234

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
print("Sending")
sock.sendto(bytearray("str()", "utf-8"), (MCAST_GRP, MCAST_PORT))

data, address = sock.recvfrom(1024)
print('received %s bytes from %s' % (len(data), address))
print(data)

receiver.py

import socket
import struct
import sys

multicast_group = '239.1.1.1'
server_address = ('', 1234)

# Create the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Bind to the server address
sock.bind(server_address)

# Tell the operating system to add the socket to the multicast group
# on all interfaces.
group = socket.inet_aton(multicast_group)
mreq = struct.pack('4sL', group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

# Receive/respond loop
while True:
    print('\nwaiting to receive message')
    data, address = sock.recvfrom(1024)

    print('received %s bytes from %s' % (len(data), address))
    print(data)

    print('sending acknowledgement to', address)
    sock.sendto(bytearray("ack", "utf-8"), address)

我有另一个物理设备连接到同一台机器,但我的程序无法从它接收任何消息。我可以看到Wireshark正在接收来自其他物理设备的消息,这些消息通过相同的IP和端口传输到eth0接口。我知道由我的脚本生成的流量在VirtualBox Host-Only Network上。我不确定这是否会导致我无法看到来自外部设备的UDP组播消息的问题。
我也在Linux机器上进行了测试(最新的kali版本),但也无法从外部设备接收任何消息。
如果我漏掉了一些信息,请告诉我。 编辑1: 我的设置如下: 我正在运行一个本地的Windows 10机器。连接到这台机器的是一个运行某些我不知道的操作系统的设备。我只能发送和接收来自它的消息。我可以通过指定我用于此的软件使用eth0和网络适配器设置中分配给该端口的定义IP(v4)地址(192.168.1.100)在我的Windows 10机器上的物理以太网端口发送以太网、TCP和IPv4数据包。
这些脚本正在运行在同一台连接到设备的Windows 10机器上。它们正在发送到这个接口VirtualBox Host-Only Network,但我不知道为什么会这样。我没有配置任何类似的东西。我认为接口不应该是一个问题,因为这就是UDP多播的工作方式(如果我错了,请告诉我!)
发送者的示例输出如下:
Sending
received 3 bytes from ('192.168.56.1', 3000)
b'ack'

Process finished with exit code 0

和接收者:

waiting to receive message
received 5 bytes from ('192.168.56.1', 55132)
b'robot'
sending acknowledgement to ('192.168.56.1', 55132)

waiting to receive message

我希望这样设置可以更清楚。如果还有遗漏的信息,请告诉我!

请尝试使用 sock.recvfrom(1) 而不是 sock.recvfrom(1024) - Hack5
你使用的确切网络配置是什么?你提到了至少3台可能的机器(Windows主机、虚拟机和外部机器)。你在哪里运行你的程序,期望使用什么接口? - Peter Brittain
@Penn 将 1024 更改为 1 会导致接收器崩溃。对于 Peter:我将更新我的问题。 - JRsz
@PeterBrittain 我更新了我的问题并添加了一些信息。 - JRsz
@JRsz 是什么错误?是在发送字节后崩溃还是之前? - Hack5
1个回答

11

正如https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html所述,套接字API要求您除了多播地址/端口外,还需指定网络接口。

由于在示例代码中未指定,因此操作系统选择了VirtualBox Host-Only Network。不幸的是,这种类型的网络仅限于运行在Windows机器上的虚拟机

为解决此问题,您需要确定要用于多播的网络接口,并将其传递给发送和接收代码。例如:

sender.py
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MCAST_IF_IP))
receiver.py
mreq = struct.pack('4s4s', group, socket.inet_aton(MCAST_IF_IP))

其中MCAST_IF_IP是您想使用的接口的IP地址。


那个有效了,所以最终是接口的问题。非常感谢!你赚到了应得的赏金!但我还有一个问题:接收器只从我的发送方发送消息的那一刻开始接收来自设备的数据包。从那时起,它会接收每个消息,但不会在此之前。你知道为什么吗? - JRsz
不客气。很抱歉,我不知道为什么你只以描述的方式看到消息。或许值得另外询问,看是否有其他人可以帮助你... - Peter Brittain
你可以看一下这个类似的问题吗?https://stackoverflow.com/questions/50878441/python3-tcp-server-not-seeing-incoming-messages-from-external-device - JRsz
这段代码在我的虚拟 Windows 10 机器上或 Ubuntu 20.04 上本地运行均失败。对 sender.py 进行的修改会抛出异常 OSError: [Errno 99] Cannot assign requested address - Marc Compere
“receiver.py” 的修改在本机 Linux 中也会导致错误:“OSError: [Errno 19] No such device”。 - Marc Compere
逻辑基于文档并经过测试,因此我预计您的错误是选择了错误的IP地址进行网络路由。 - Peter Brittain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接