【问题标题】:Bind both IPv4 and IPv6 source address to python socket将 IPv4 和 IPv6 源地址绑定到 python 套接字
【发布时间】:2015-12-25 16:25:39
【问题描述】:

我有一个 python 应用程序,它需要为 IPv6 连接选择特定的本地源地址,但可以将“任何”0.0.0.0 用于 IPv4 连接。但是应用程序使用socket.connect((host, port)) 中的主机名来允许socket.connect() 从名称中查找地址。

鉴于在调用 socket.connect() 之前我不知道 IPv4 地址或 IPv6 地址是否会从名称查询?

现在我正在处理它,但 socket.EAI_ADDRFAMILY 有一个例外:

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()。这样,当我进行本地地址绑定时,我就会知道socket.connect() 将使用 IPv4 还是 IPv6。但是,我不得不重新实现 socket.connect() 已经完成的名称解析和选择,这对我来说似乎很愚蠢。

【问题讨论】:

    标签: python sockets network-programming ipv6 ipv4


    【解决方案1】:

    您不能将多个地址绑定到同一个套接字,也不能将两次绑定到同一个套接字。相反,您必须首先使用getaddrinfo 解析地址,然后将低级connect 与您从getaddrinfo 获得的sockaddr 一起使用。 getaddrinfo 还会告诉您这是哪种类型的套接字,以便您可以绑定到 IPv6 地址,以防您必须连接到 IPv6 地址。

    【讨论】:

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