繁体   English   中英

Python 检查网络连接

[英]Python check For network connection

我想知道是否有任何 python 脚本(更好的命令)可以告诉我我是否已连接到网络。

我不是在谈论“互联网”,我在谈论有线或无线“网络”(所以请不要将此问题设置为重复)

我的意思是我的调制解调器路由器已打开并且我已连接到它(并且它是否具有互联网并不重要)所以脚本返回 True (最好不要建议像 ping 等终端命令)

还有另一个问题可能是这个问题的答案:获取requests.get('192.168.1.1').status_code是否很好,如果它是 200,我们是否已连接到网络?

还有另一个问题可能是这个问题的答案:获取 requests.get('192.168.1.1').status_code 是否很好,如果它是 200,我们是否已连接到网络?

这不是个好主意。

  • 如果本地网络不是192.168.1.0/24怎么办?
  • 如果网关不是192.168.1.1怎么办?
  • 如果路由器没有 HTTP 接口怎么办?

您可以做的唯一明智的事情是选择一个众所周知的端点(例如“google.com”)并尝试联系它(例如requests.get("http://google.com") )。 如果它有效……太好了,你就连接上了! 如果它不起作用,则您没有足够的信息来决定是否已连接。

如果您只对本地网络连接感兴趣,您可以首先确定您的默认网关地址(例如通过在 Linux 下运行ip route ,或在 Windows 上运行route print ),然后尝试 ping 那个。 再一次,您只能检测到一个肯定的情况:如果您收到响应,则表示已连接,但如果没有,则不知道是否已连接。

@larsks 所说的一切都是正确的。 您可以检查您的主机(或只有本地主机)上是否有 IP 地址。

你可以做什么 :

  • 检查您的盒子上是否有 IP 地址,该地址与 localhost、环回地址范围不同

  • 如果您知道默认网关(您可以得到它)您可能会 ping 默认网关 - 但这可能会失败,因为 ICMP ping 数据包可能在该默认网关上被禁用。

避免 TOCTOU 错误 - 只需使用地址并捕获错误! (参见: https : //en.wikipedia.org/wiki/Time-of-check_to_time-of-use

这里我通常在那种情况下使用的功能:

def get_host_ip_or_localhost() -> Union[str, None]:
    """
    >>> result = get_host_ip_or_localhost()
    >>> assert is_valid_ip_adress(result)
    """
    host_ip = get_host_ip()

    if not host_ip:                                                                     # pragma: no cover
        logger.warning('can not get default gateway IP, setting localhost as IP')       # pragma: no cover
        host_ip = socket.gethostbyname('localhost')                                     # pragma: no cover
    return host_ip


def ip_is_localhost(host_ip: str) -> bool:
    """
    >>> ip_is_localhost('127.0.0.1')
    True
    >>> ip_is_localhost('localhost')
    True
    >>> ip_is_localhost('192.168.168.17')
    False
    >>> ip_is_localhost('192.168.168.254')
    False
    """
    host_ip = socket.gethostbyname(host_ip)
    local_host_ip = socket.gethostbyname('localhost')
    if host_ip == local_host_ip or host_ip.startswith('127.'):
        return True
    else:
        return False


def get_host_ip() -> Union[str, None]:
    """
    >>> result = get_host_ip()
    >>> assert is_valid_ip_adress(result)
    """
    o_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # noinspection PyBroadException
    try:
        # doesn't even have to be reachable
        o_socket.connect(('1.1.1.1', 1))
        s_ip = str(o_socket.getsockname()[0])  # type: Union[str, None]
    except Exception:           # pragma: no cover
        s_ip = None             # pragma: no cover
    finally:
        o_socket.close()
    return s_ip


def is_internet_connected(ip_adress: str = '1.1.1.1') -> bool:
    """
    >>> is_internet_connected()
    True
    >>> is_internet_connected(ip_adress='www.un-kno-wn.com')
    False
    """
    response = lib_ping.ping(target=ip_adress, times=1)
    return bool(response.reached)


def is_valid_ip_adress(address: str) -> bool:
    """
    check if it is valid IPV4 or IPV6 Adress
    >>> is_valid_ip_adress('1.1.1.1')
    True
    >>> is_valid_ip_adress('::1')
    True
    >>> is_valid_ip_adress('unknown')
    False
    """
    if is_valid_ipv4_address(address) or is_valid_ipv6_address(address):
        return True
    else:
        return False


def is_valid_ipv4_address(address: str) -> bool:
    """
    >>> is_valid_ipv4_address('1.1.1.1')
    True
    >>> is_valid_ipv4_address('1.1.1.')
    False
    >>> is_valid_ipv4_address('unknown')
    False
    """
    try:
        socket.inet_pton(socket.AF_INET, address)
    except AttributeError:                      # pragma: no cover      # no inet_pton here, sorry
        try:                                    # pragma: no cover
            socket.inet_aton(address)           # pragma: no cover
        except socket.error:                    # pragma: no cover
            return False                        # pragma: no cover
        return address.count('.') == 3          # pragma: no cover
    except socket.error:                        # not a valid address
        return False

    return True


def is_valid_ipv6_address(address: str) -> bool:
    """
    >>> is_valid_ipv6_address('::1')
    True
    >>> is_valid_ipv6_address('127.0.0.1')
    False
    >>> is_valid_ipv6_address('unknown')
    False
    """
    try:
        socket.inet_pton(socket.AF_INET6, address)
    except socket.error:  # not a valid address
        return False
    return True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM