我有一个 python 应用程序需要为 IPv6 连接选择特定的本地源地址,但可以为 IPv4 连接使用“任何”0.0.0.0。但是应用程序在 socket.connect((host, port))
中使用主机名,以允许 socket.connect()
从名称中查找地址。
那么我如何将特定的 IPv6 源地址和 IPv4“任何”地址绑定(bind)到本地套接字,因为在调用 socket.connect()
之前我不知道 IPv4地址或 IPv6 地址将来自名称查找?
现在我正在处理它,但在 socket.EAI_ADDRFAMILY
上有一个异常(exception):
try:
sock.bind(("2601:a2a0:a0aa:1d00:aeaa:aaff:aa6c:aaab",0))
sock.connect((host, port))
except socket.gaierror, e:
if e[0] == socket.EAI_ADDRFAMILY:
sock.bind(("0.0.0.0",0))
sock.connect((host, port))
但是当然不能保证异常处理程序中的 socket.connect()
会仅仅因为先前的 socket.connect()
将主机解析为 IPv4 地址> 做了。
一定有更好的方法。我怀疑我必须自己实现地址查找和选择,并将地址而不是名称传递给 socket.connect()
。这样,当我进行本地地址绑定(bind)时,我就会知道 socket.connect()
将使用 IPv4 还是 IPv6。但对我来说,必须重新实现 socket.connect()
已经完成的名称解析和选择似乎很愚蠢。
最佳答案
您不能将多个地址绑定(bind)到同一个套接字,也不能将两次绑定(bind)到同一个套接字。相反,您必须先使用 getaddrinfo 解析地址然后使用低级 connect使用从 getaddrinfo 获得的 sockaddr。 getaddrinfo 还会告诉您这是哪种类型的套接字,以便您可以绑定(bind)到 IPv6 地址,以防您必须连接到 IPv6 地址。
关于python - 将 IPv4 和 IPv6 源地址绑定(bind)到 python 套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32822810/