【问题标题】:not seeing UDP multicast messages from another device看不到来自另一台设备的 UDP 多播消息
【发布时间】:2018-11-01 07:25:09
【问题描述】:

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

发件人.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 正在查看来自其他物理设备的消息,这些消息通过 eth0 接口发送到相同的 IP 和端口。我知道我的脚本生成的流量在VirtualBox Host-Only Network 上。我不确定这是否会导致我看不到来自外部设备的 UDP 多播消息。

我也在 Linux 机器上测试过(最新的 kali 版本),但也无法从外部设备接收到任何消息。

如果我遗漏了一些信息,请告诉我。

编辑 1:

我的设置如下: 我正在运行本机 Windows 10 机器。这台机器是一个连接的设备,它正在运行一些我不知道的操作系统。我只能从中发送和接收消息。我可以通过在我的 Windows 10 机器上的物理以太网端口发送以太网、TCP 和 IPv4 数据包,方法是指定我用于此的软件以使用 eth0 和我在网络适配器设置中分配给该端口的已定义 IP(v4) 地址(192.168.1.100)

脚本在也连接到设备的同一台 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)
  • 您使用的确切网络配置是什么?您提到至少 3 台可能的机器(Windows 主机、VM 和外部机器)。您在哪里运行您的程序以及您希望使用哪些接口?
  • @Penn 从 1024 更改为 1 会导致接收器崩溃。对于彼得:我会更新我的问题
  • @PeterBrittain 我已经更新了我的问题并添加了一些信息
  • @JRsz 错误是什么?它是在您发送字节之后还是之前崩溃?

标签: python python-3.x interface udp multicast


【解决方案1】:

正如https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html 中所述,套接字 API 要求您识别接口以及要使用的多播地址/端口。

通过在示例代码中未指定此内容,您已将其留给操作系统来选择,并且它选择了 VirtualBox Host-Only 网络。不幸的是,这种类型的网络是limited to VMs running on the Windows machines

要修复它,您需要确定要用于多播的接口并将其传递给您的发送和接收代码。例如:

发件人.py
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MCAST_IF_IP))
接收器.py
mreq = struct.pack('4s4s', group, socket.inet_aton(MCAST_IF_IP))

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

【讨论】:

  • 那行得通,所以它毕竟是界面。非常感谢!赏金好赚!但我还有一个问题:接收方仅从我的发送方发送消息的那一刻起接收来自设备的数据包。从那以后,它会收到每条消息,但之前不会。你知道为什么会这样吗?
  • 不客气。对不起,但我不知道为什么您只能以您描述的方式看到消息。可能值得单独询问,看看是否有其他人可以帮助您....
  • 你也可以看看这个类似的问题吗? stackoverflow.com/questions/50878441/…
  • 这不适用于我的虚拟 Windows 10 机器或本机 Ubuntu 20.04。 sender.py 修改抛出异常 OSError: [Errno 99] Cannot assign requested address
  • receiver.py 修改在原生 linux 中也会导致错误:OSError: [Errno 19] No such device
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多