首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测是否支持IPv6,操作系统无关,没有外部程序?

检测是否支持IPv6,操作系统无关,没有外部程序?
EN

Stack Overflow用户
提问于 2021-02-17 16:43:52
回答 2查看 181关注 0票数 1

是否有一种方法可以检测系统上是否支持IPv6,而无需使用外部程序和操作系统无关的方式?

我到处搜索,这里和整个互联网,似乎几乎每一个提供的解决方案都依赖于访问/proc (在Windows和MacOS上不可用)或运行外部程序。

我想出的最好办法是:

代码语言:javascript
复制
import errno
import socket

def has_ip6():
    try:
        socket.create_connection(("::1", 0))
    except OSError as e:
        if e.errno == errno.EADDRNOTAVAIL:
            return False
        if e.errno == errno.ECONNREFUSED;
            return True
        raise

有更好的办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-17 21:03:14

尽管@averresen的答案不正确,但它确实使我找到了https://github.com/urllib3/urllib3/pull/611#issuecomment-100954017中指定的正确答案:

代码语言:javascript
复制
def _is_ipv6_enabled():
    """Check whether IPv6 is enabled on this host."""
    if socket.has_ipv6:
        sock = None
        try:
            sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
            sock.bind((HOSTv6, 0))
            return True
        except OSError:
            pass
        finally:
            if sock:
                sock.close()
    return False

所以基本上,我所做的已经走上了正确的道路,我只需要在开始的时候添加一个防御的if not socket.has_ipv6: return False

编辑1:

这就是我最后的结局:

代码语言:javascript
复制
import socket
import errno

# On Windows, the E* constants will use the WSAE* values
# So no need to hardcode an opaque integer in the sets.
_ADDR_NOT_AVAIL = {errno.EADDRNOTAVAIL, errno.EAFNOSUPPORT}
_ADDR_IN_USE = {errno.EADDRINUSE}

def system_has_ipv6() -> bool:
    if not has_ipv6:
        return False
    try:
        with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as sock:
            sock.bind(("::1", 0))
        return True
    except OSError as e:
        if e.errno in _ADDR_NOT_AVAIL:
            return False
        if e.errno in _ADDR_IN_USE:
            # This point shouldn't ever be reached. But just in case...
            return True
        # Other errors should be inspected
        raise

编辑2:

我将errno.EAFNOSUPPORT添加到_ADDR_NOT_AVAIL集中。如果加载了EADDRNOTAVAIL模块/驱动程序,则IPv6是errno,但如果IPv6模块/驱动程序根本没有加载,则EAFNOSUPPORT是errno。

票数 1
EN

Stack Overflow用户

发布于 2021-02-17 16:47:26

socket.has_ipv6**编辑:不要使用查看@pepoluan自己的答案!**

套接字模块包含常量ipv6,专门用于指示是否支持IPv6。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66246308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档