问题描述
我正在尝试使用此 python 2.7 代码在 Windows 上接收 IPv6 多播数据包(发送到 ff02::1 地址)-
I am trying to receive IPv6 multicast packets (sent to the ff02::1 address) on Windows using this python 2.7 code-
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接口.虽然我在使用 Wireshark 嗅探以太网连接时能够看到相关的数据包,但此代码没有接收到数据包.
I send packets from another computer that is connected to my computer via Ethernet; in addition, my computer also has a WiFi interface. Although I'm able to see the relevant packets when sniffing the Ethernet connection with Wireshark, the packets are not received by this code.
但是,当我禁用 WiFi 网卡时,会收到数据包.这让我觉得当 WiFi 接口启用时,代码只监听来自该接口的数据包.
However, when I disable the WiFi network card, the packets are received. This makes me think that while the WiFi interface is enabled the code listens only to packets from that interface.
我读到绑定到 ""
应该能够接收来自所有网络接口的数据包,但由于某种原因它对我不起作用.
I read that binding to ""
should enable receiving packets from all network interfaces, but for some reason it doesn't work for me.
有人对我忘记做的事情有任何想法吗?或解决此问题的不同方法?
Does anyone have any idea to something that I have forgotten to do? or a different way to solve this?
谢谢!
推荐答案
解决了:)
显然 IPv6 不从所有接口监听多播.这个语法
So apparently IPv6 doesn't listen to multicast from all interfaces. This syntax
mreq = group + struct.pack('@I', 0)
错了.根据 这个,mreq 由组 id 和接口 id 组成,其中 0 是默认接口(在我的例子中是 WiFi).为了侦听来自其他接口的多播,应指定网络接口索引.
was wrong. According to this, mreq is composed of the group id and the interface id, where 0 is the default interface (in my case- WiFi). In order to listen to multicast from other interfaces, the network interface index should be specified.
网络接口索引是运行ipconfig时ipv6地址中%
后面出现的数字,也可以在cmd中运行route print"找到.
The network interface index is the number thet appears after the %
in the ipv6 address when running ipconfig, and can also be found running "route print" in cmd.
我用这段代码在python上找到它:
I used this code to find it on 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'SYSTEMCurrentControlSetControlNetwork{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())
这篇关于Windows 不接收来自所有接口的多播 IPv6 数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!