【问题标题】:RAW socket UDP Multicast in IPv6IPv6 中的 RAW 套接字 UDP 多播
【发布时间】:2017-03-20 23:34:56
【问题描述】:

我为我的 UDP 嗅探器接收来自多播的数据,但仅限于 IPv4。 我的代码是这样的,

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
except socket.error as msg:
    print('Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
    sys.exit()

mreq = struct.pack("4sl", socket.inet_aton('239.255.11.3'), socket.INADDR_ANY)
# receive a packet

s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

packet = s.recvfrom(65000)

但我只有在设置 IPv4 地址时才接收数据,而且我还想从 IPv6 多播地址接收数据。 我将非常感谢任何想法,并对我的英语感到抱歉。 ;-)

【问题讨论】:

  • 我的想法是这样的:s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IP_PROTO_UDP) 和 s.setsockopt(socket.IPPROTO_IP, socket.IPV6_JOIN_GROUP, mreq) 但我不知道,如何“打包”mreq 或设置它。

标签: python sockets udp ipv6 multicast


【解决方案1】:

此示例在 Windows 中的 FF02::158 (IoTivity UDP CoAP) 上获取多播

import socket
import struct

address = ('', 5683)
interface_index = 0  # default

sock = socket.socket(family=socket.AF_INET6, type=socket.SOCK_DGRAM)
sock.bind(address)
for group in ['ff02::158']:  # multiple addresses can be specified
    sock.setsockopt(
        41,  # socket.IPPROTO_IPV6 = 41 - not found in windows 10, bug python
        socket.IPV6_JOIN_GROUP,
        struct.pack(
            '16si',
            socket.inet_pton(socket.AF_INET6, group),
            interface_index
        )
    )

while True:
    data, sender = sock.recvfrom(1500)
    while data[-1:] == '\0': data = data[:-1]  
    print(str(sender) + '  ' + repr(data))

更完整的答案 https://stackoverflow.com/a/66943594/8625835

【讨论】:

    【解决方案2】:

    这就是我在my code做的事情:

    mc_address = ipaddress.IPv6Address('ff02::1:2')
    listen_port = 547
    interface_index = socket.if_nametoindex('eth0')
    
    mc_sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    mc_sock.bind((str(mc_address), listen_port, 0, interface_index))
    mc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP,
                       struct.pack('16sI', mc_address.packed, interface_index))
    

    这是针对 DHCPv6 服务器的,但您会明白的。

    如果你也想获得自己传输的组播数据包,你必须添加:

    mc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
    

    【讨论】:

      【解决方案3】:

      您需要使用 sockopt IPV6_ADD_MEMBERSHIP,因为 IPv6 和 IPv4 之间的 API 略有不同。 This 就是一个很好的例子。

      【讨论】:

      • 好的,谢谢。你知道如何像上面我添加的代码那样设置“mreq”吗? (mreq = struct.pack("4sl", socket.inet_aton('239.255.11.3'), socket.INADDR_ANY)) 我不知道怎么打包。
      • ipv6_mreq 是一个 16 字节的地址,一个无符号的 int 接口索引。试试 mreq6 = struct.pack("16sI", socket.inet_pton( AF_INET6, 'your ip v6 group' ), 0 )
      • 我可以用 0 socket.INADDR_ANY 代替吗?我从一些网络示例中得到了这部分代码,但我不太明白,但我想当我使用 INADDR_ANY 时,我会监听所有端口。
      猜你喜欢
      • 2021-12-01
      • 2017-12-30
      • 2014-07-12
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      相关资源
      最近更新 更多