Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python IPv6中的原始套接字UDP组播_Python_Sockets_Udp_Ipv6_Multicast - Fatal编程技术网

Python IPv6中的原始套接字UDP组播

Python IPv6中的原始套接字UDP组播,python,sockets,udp,ipv6,multicast,Python,Sockets,Udp,Ipv6,Multicast,我从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

我从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多播地址接收数据。
如果有任何想法,我都会非常感激,对于我的英语,我也会感到抱歉。;-)

您需要使用sockopt IPV6_ADD_成员身份,因为IPV6和IPv4之间的API略有不同。这是一个很好的例子。

这就是我正在做的:

mc_address=ipaddress.ipv6地址('ff02::1:2')
监听端口=547
接口索引=socket.if\u name索引('eth0')
mc_sock=socket.socket(socket.AF_INET6,socket.sock_DGRAM,socket.IPPROTO_UDP)
mc_sock.bind((str(mc_地址),侦听端口,0,接口索引))
mc_sock.setsockopt(socket.IPPROTO_IPV6,socket.IPV6_加入_组,
结构包('16sI',mc_地址包,接口索引))
这是针对DHCPv6服务器的,但您会明白的

如果您还希望自己发送多播数据包,则必须添加:

mc_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 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))
更全面的回答

我的想法是:s=socket.socket(socket.AF_INET6,socket.SOCK_RAW,IP_PROTO_UDP)和s.setsockopt(socket.IPPROTO_IP,socket.IPV6_JOIN_GROUP,mreq),但我不知道如何“打包”或设置mreq。好的,谢谢。你们知道如何设置“mreq”吗,就像我上面添加的代码一样?(mreq=struct.pack(“4sl”,socket.inet\u aton('239.255.11.3'),socket.INADDR\u ANY))我不知道如何打包。ipv6\u mreq是一个16字节的地址,是一个无符号的int接口索引。请尝试mreq6=struct.pack(“16sI”,socket.inet\u pton(AF\u INET6,“您的ip v6组”),0),并且可以使用iI代替0 socket.INADDR\u吗?我从net的某个示例中得到了这部分代码,但我不太明白,但我想当我使用INADDR_ANY时,我会监听所有端口。