在Python中发送和接收IPv6链路本地多播UDP数据报?

发布于 2024-09-08 14:41:30 字数 740 浏览 3 评论 0原文

下面是一个简单的 IPv4 UDP 广播,然后在所有接口上进行侦听。

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.bind(("", 1337))
sock.sendto("hello world", ("255.255.255.255", 1337))
while True:
    data, addr = sock.recvfrom(0x100)
    print "received from {0}: {1!r}".format(addr, data)

我想调整它以发送和接收 IPv4 和 IPv6。

我已经尽可能多地查阅和阅读,并相信以下大致是我需要采取的路线:

  1. 创建 IPv6 套接字。
  2. 将套接字添加到链路或站点本地多播组。
  3. 将 UDP 数据包发送到正在使用的组的多播地址。

我得到的进一步信息是,我可能需要绑定到多个接口,并使用 setsockopt() 告诉套接字它还应该接收多播数据包。最后,可以全面使用 getaddrinfo() 在 IPv6 不可用的情况下优雅地“回退”到 IPv4。

我已经实现了大部分内容,但主要是在多播部分上遇到了困难。最好有完整的Python代码示例,或者对所需常量和地址进行生动的描述。

This following is a straightforward IPv4 UDP broadcast, followed by listening on all interfaces.

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.bind(("", 1337))
sock.sendto("hello world", ("255.255.255.255", 1337))
while True:
    data, addr = sock.recvfrom(0x100)
    print "received from {0}: {1!r}".format(addr, data)

I want to adjust this to send and receive both IPv4 and IPv6.

I've poked around and read as much as I can and believe the following is roughly the route I need to take:

  1. Create an IPv6 socket.
  2. Add the socket to a link or site local multicast group.
  3. Send the UDP packets to the multicast address for the group in use.

Further info I have is that I may need to bind to several interfaces, and tell the socket using setsockopt() that it should also receive multicast packets. Lastly getaddrinfo() can be used across the board to gracefully "drop back" to IPv4 where IPv6 isn't available.

I have much of this implemented, but stumble primarily on the multicasting parts. A complete code example in Python, or vivid description of the constants and addresses needed are preferred.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稀香 2024-09-15 14:41:30

这是 python mcast demo 的链接,两者都可以IPv4 和 IPv6。

Here's a link to python mcast demo, does both IPv4 and IPv6.

遮云壑 2024-09-15 14:41:30

我目前正在此处提出一个涉及获取多播的问题收到消息的地址,但源代码回答了您的问题!

收听:

# Initialise socket for IPv6 datagrams
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

# Allows address to be reused
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Binds to all interfaces on the given port
sock.bind(('', 8080))

# Allow messages from this socket to loop back for development
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)

# Construct message for joining multicast group
mreq = struct.pack("16s15s".encode('utf-8'), socket.inet_pton(socket.AF_INET6, "ff02::abcd:1"), (chr(0) * 16).encode('utf-8'))
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)

data, addr = sock.recvfrom(1024)

和发送:

# Create ipv6 datagram socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
# Allow own messages to be sent back (for local testing)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)
sock.sendto("hello world".encode('utf-8'), ("ff02::abcd:1", 8080))

这是针对 python3.6 的,对于 python 2.7,我认为编码不是必需的。同样在 struct.pack 行中,我看到了“16s15s”的变体,例如“4s”,但我不知道它是什么以及我为我工作了什么!

I'm currently asking a question over here that involves getting the multicast address of a received message, but the source code answers your question!

To listen:

# Initialise socket for IPv6 datagrams
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

# Allows address to be reused
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Binds to all interfaces on the given port
sock.bind(('', 8080))

# Allow messages from this socket to loop back for development
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)

# Construct message for joining multicast group
mreq = struct.pack("16s15s".encode('utf-8'), socket.inet_pton(socket.AF_INET6, "ff02::abcd:1"), (chr(0) * 16).encode('utf-8'))
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)

data, addr = sock.recvfrom(1024)

and to send:

# Create ipv6 datagram socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
# Allow own messages to be sent back (for local testing)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)
sock.sendto("hello world".encode('utf-8'), ("ff02::abcd:1", 8080))

This is for python3.6, with python 2.7 I don't think the encodes are necessary. Also in the struct.pack line, I've seen variations of "16s15s" such as "4s", but I don't know what it is and what I have worked for me!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文