3

我目前正在为通过 IPv6 链接本地地址进行网络通信的 C++ 库编写 python 包装器。要初始化库,必须选择网络接口。这是通过所需接口的链路本地地址完成的。

在 C++ 端,我们使用 boost address_v6 objects。在 python 方面,ipaddress.IPv6Address似乎是一个完美的匹配。

但是我没有找到一种方法来指定python端接口的范围ID。

ip = ipaddress.IPv6Address('fe80::3c4e:6a7:3f57:4cbc%12')

给出错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python34\lib\ipaddress.py", line 1835, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "C:\Python34\lib\ipaddress.py", line 1664, in _ip_int_from_string
    raise AddressValueError("%s in %r" % (exc, ip_str)) from None
ipaddress.AddressValueError: Only hex digits permitted in '4cbc%12' in 'fe80::3c4e:6a7:3f57:4cbc%12'

如果没有范围 ID,IPv6 链路本地通信几乎是不可能的。

我在这里遗漏了什么还是将 IPv6 链路本地接口地址指定为字符串的最佳方法?

4

2 回答 2

0

在所有有意义的情况下,我建议使用与 Python 套接字模块相同的结构。即使使用您的本机库意味着不会使用 Python 套接字模块,但如果某些数据结构在两者之间兼容,它仍然是有益的。

为了表示 IP 地址,Python 套接字模块确实使用了字符串。并且该字符串可以在适当的时候包含范围 ID。

Python 套接字模块还需要为此目的表示套接字地址,它使用由四个字段组成的元组。例如,它可以是:

('ff02::2%eth0', 80, 0, 2)

请注意,这种表示方式有点多余,因为作用域 ID 既指定为%eth0IP 地址内部,也指定为2(元组的最后一个元素)。

于 2015-03-14T11:42:38.263 回答
0
((*_, sockaddr),) = socket.getaddrinfo(
    'ff02::1de:c0:face:8D%42',
    1234,
    socket.AF_INET6,
    socket.SOCK_DGRAM,
    socket.IPPROTO_UDP
)

assert sockaddr == ('ff02::1de:c0:face:8d', 1234, 0, 42)

https://github.com/python/cpython/pull/4724

于 2018-01-26T16:40:24.770 回答