尝试将python套接字绑定到IPv6地址时参数无效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试将python套接字绑定到IPv6地址时参数无效相关的知识,希望对你有一定的参考价值。

我正在尝试从我的虚拟机将我在python中的套接字绑定到我的其他虚拟机的地址,以便我可以嗅探由两者交换的帧。所以这是我的代码

    import socket

UDP_IP = "fe80:849b:21f4:624c:d70b"
UDP_PORT = 61627

sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024)
    print(data)

当我尝试执行我的python时,收到一条错误消息:

sock.bind((UDP_IP, UDP_PORT))
socket.error: [Error 22] Invalid argument

我做错了什么,提前谢谢!

答案

我打赌,你已经找到了答案,但是第一眼看到我的代码有两个问题:

  1. 在IPv6中,fe80 :: / 10地址块保留用于链路本地地址。这些地址仅对本地子网有效,因此它们与范围后缀(如%eth0)一起使用以指定适当的范围。其中eth0是IPv6地址有效的网络接口的名称。

因此对于我的Mac笔记本电脑,UDP IP地址可能如下所示:

UDP_IP = "fe80:849b:21f4:624c:d70b%en0"
  1. 接下来,指定(UDP_IP,UDP_PORT)元组对IPv4绝对有效,但对于IPv6,此元组还应包含flow_info和scope_id字段。有时,可以省略或遗漏flow_info和scope_id:(UDP_IP,UDP_PORT,0,0)。它有时可能会起作用,但它不是在代码中使用的正确方法。

因此,可以通过socket.getaddrinfo(IP,PORT)获取这些字段,它返回每个地址族和socket_kind的元组列表。用这样的东西过滤它们:

for ainfo in socket.getaddrinfo(UDP_IP, UDP_PORT):
    if ainfo[0].name == 'AF_INET6' and ainfo[1].name == 'SOCK_DGRAM':
        target_address = ainfo[4]
        break

sock.bind(target_address)

我不确定,如果我正确编写示例代码,因为我没有测试它,请在使用前检查它。

以上是关于尝试将python套接字绑定到IPv6地址时参数无效的主要内容,如果未能解决你的问题,请参考以下文章

网络上的Python套接字ipv6不起作用

ZeroMQ 在套接字绑定到 ipc:// 协议地址(python)时抛出 ZMQError

错误:在将套接字与地址绑定时地址已在使用中,但端口号由“netstat”免费显示

Python网络编程之TCP服务端程序开发

windows winsock2 socket从WSAGetLastError返回10014 WSAEFAULT(ipv4 / ipv6相关)

将套接字重新绑定到不同的接口