python - 将 IPv4 和 IPv6 源地址绑定(bind)到 python 套接字

标签 python sockets network-programming ipv6 ipv4

我有一个 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/

相关文章:

c++ - 虚拟试衣间设计

java - 如何通过tcp/ip从java接收文件到C?

http - HTTP 中的 header 接受

C# 已建立的连接被主机中的软件中止

python - 为什么list reverse返回Null?

python - 如何在 AppEngine 中获取基本 URI?

python - 如何直接在 Pandas DataFrame 中的 PDF 上计算统计指标?

c# - 套接字开始变慢并且没有响应

ios - IPV6 连接到 IPV4 TOS 选项

c - libpcap - 数据包 ip header 长度为零字节,带有环回 tcp 请求