【问题标题】:Invalid argument when trying to bind python socket to IPv6 address尝试将 python 套接字绑定到 IPv6 地址时参数无效
【发布时间】:2018-09-22 08:52:37
【问题描述】:

我正在尝试从我的虚拟机将我在 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

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

【问题讨论】:

  • 该 IPv6 地址无效。
  • 为什么无效?
  • 因为它没有强制作用域ID。

标签: python sockets udp ipv6


【解决方案1】:

我敢打赌,你已经找到了答案,但乍一看我发现你的代码有两个问题:

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

所以对于我的 MacOS 笔记本电脑,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)

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

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 2012-06-15
    • 2020-02-20
    • 2021-04-28
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    相关资源
    最近更新 更多