Windows不会从所有接口接收组播IPv6数据包

我试图在Windows上使用这个Python 2.7代码接收IPv6多播数据包(发送到ff02 :: 1地址)

import socket import win_inet_pton import struct socket.IPPROTO_IPV6=41 #because using python 2.7 on wondows PORT = 1234 UDP_BROADCAST_IPv6 = "ff02::1" sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(("",PORT)) # not working with "::" either # Join multicast group addrinfo = socket.getaddrinfo(UDP_BROADCAST_IPv6, None)[0] group = socket.inet_pton(addrinfo[0], addrinfo[4][0]) mreq = group + struct.pack('@I', 0) sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) while True: msg=sock.recv(1024) print msg 

我从另一台通过以太网连接到计算机的计算机发送数据包; 另外,我的电脑还有一个WiFi接口。 尽pipe在用Wireshark嗅探以太网连接时我能够看到相关的数据包,但这些数据包没有被这个代码接收。

但是,当我禁用WiFi网卡时,数据包被接收。 这使我认为,虽然启用了WiFi接口,但代码只侦听来自该接口的数据包。

我读到绑定到“”应该能够接收来自所有networking接口的数据包,但由于某种原因,它不适用于我。

有没有人有任何想法,我忘了做什么? 或以不同的方式来解决这个问题?

谢谢!

解决了:)

所以显然,IPv6 不会监听来自所有接口的多播。 这个语法

 mreq = group + struct.pack('@I', 0) 

错了。 据此,mreq由组ID和接口ID组成,其中0是默认接口(在我的情况下是WiFi)。 为了监听来自其他接口的组播,应该指定网络接口索引。

网络接口索引是运行ipconfig时在ipv6地址中的%出现的数字,也可以在cmd中运行“route print”。

我用这个代码在python上找到它:

 import netifaces as ni import _winreg as wr # use "winreg" in python3 def get_ethernet_ipv6_ifindex(): x=ni.interfaces() con_names=get_connection_name_from_guid(x) ethernet_index= con_names.index('Ethernet') addresses= ni.ifaddresses(x[ethernet_index]) brod_addr=addresses[socket.AF_INET6][-1]["broadcast"] return int(brod_addr[brod_addr.find("%")+1:]) """ Taken from the very helpful https://stackoverflow.com/questions/29913516/how-to-get-meaningful-network-interface-names-instead-of-guids-with-netifaces-un """ def get_connection_name_from_guid(iface_guids): iface_names = ['(unknown)' for i in range(len(iface_guids))] reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE) reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}') for i in range(len(iface_guids)): try: reg_subkey = wr.OpenKey(reg_key, iface_guids[i] + r'\Connection') iface_names[i] = wr.QueryValueEx(reg_subkey, 'Name')[0] except WindowsError: pass return iface_names 

接着-

 mreq = group + struct.pack('@I', get_ethernet_ipv6_ifindex())