代码之家  ›  专栏  ›  技术社区  ›  Jeremy Friesner

为什么在Python中%en0后缀不能连接链路本地IPv6 TCP套接字?

  •  7
  • Jeremy Friesner  · 技术社区  · 15 年前

    asked 为什么他们连接到IPv6链路本地地址的Python代码不起作用,我回答说,因为这是一个链路本地地址,所以他们需要在目标IP地址上添加一个%en0(或任何所需的本地接口名称)后缀。我以为我知道自己在说什么,所以在回答之前,我并没有真正测试我的建议(真让我羞愧!)。

    今天我自己也用了同样的方法,结果发现好像没用。:^(即,此代码不起作用:

    >>> from socket import *
    >>> s = socket(AF_INET6, SOCK_STREAM)
    >>> s.connect(('fe80::21f:5bff:fe3f:1b36%en0', 2001))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1, in connect
    socket.error: [Errno 65] No route to host
    

    另一方面,以下代码确实有效(带或不带%en0后缀):

    >>> from socket import *
    >>> s = socket(AF_INET6, SOCK_STREAM)
    >>> s.connect(('fe80::21f:5bff:fe3f:1b36%en0', 2001, 0, 6))
    >>> 
    

    ... 但我不喜欢这样做,因为为了找出要为最后一个参数提供哪个作用域I d整数,我必须执行一堆不太可移植的代码来遍历本地接口列表,找到名为“en0”的接口,并提取其作用域ID,这比我希望的要复杂得多。

    考虑到connect()接受IP地址的%en0后缀,它为什么不按预期使用它来确定作用域ID?

    1 回复  |  直到 9 年前
        1
  •  13
  •   Jerub    15 年前

    这是进行ipv6连接的正确方法:

    >>> addrinfo = getaddrinfo('fe80::225:ff:fecd:5aa0%en0', 2001, AF_INET6, SOCK_STREAM)
    >>> addrinfo
    [(30, 1, 6, '', ('fe80::225:ff:fecd:5aa0%en0', 2001, 0, 4))]
    >>> (family, socktype, proto, canonname, sockaddr) = addrinfo[0]
    >>> s = socket(family, socktype, proto)
    >>> s.connect(sockaddr)
    

    getaddrinfo() 将为您返回正确的数值范围和流量信息。

    推荐文章