首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何查看Python中是否有可用的活动网络连接?

如何查看Python中是否有可用的活动网络连接?
EN

Stack Overflow用户
提问于 2010-09-22 04:39:15
回答 21查看 216.8K关注 0票数 155

我想看看我是否可以访问在线API,但为了实现这一点,我需要有Internet访问权限。

如何使用Python查看是否有可用的活动连接?

EN

回答 21

Stack Overflow用户

回答已采纳

发布于 2010-09-22 05:31:52

也许你可以使用这样的东西:

代码语言:javascript
复制
import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False

目前,216.58.192.142是google.com的IP地址之一。将http://216.58.192.142更改为任何可以快速响应的站点。

此固定IP不会永远映射到google.com。所以这段代码并不健壮--它需要不断的维护才能使其正常工作。

上面代码使用固定IP地址而不是完全限定域名( FQDN )的原因是因为FQDN需要DNS查找。当机器没有工作的互联网连接时,DNS查找本身可能会阻止对urllib_request.urlopen的调用超过一秒钟。感谢@rzetterberg指出这一点。

如果上面的固定IP地址不起作用,您可以通过运行以下命令查找google.com (在unix上)的当前IP地址

代码语言:javascript
复制
% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142
票数 143
EN

Stack Overflow用户

发布于 2015-10-14 13:51:53

如果我们可以连接到某个Internet服务器,那么我们就确实有了连接。但是,为了实现最快、最可靠的方法,所有解决方案至少应符合以下要求:

  • 避免DNS解析(我们将需要一个众所周知且保证大多数时间都可用的IP )
  • 避免应用层连接(连接到HTTP/FTP/IMAP服务)
  • 避免从Python或其他选择的语言调用外部实用程序(我们需要想出一个不依赖于第三方解决方案的语言无关的解决方案)

要符合这些要求,一种方法可能是检查其中一个Google's public DNS servers是否可达。这些服务器的IPv4地址为8.8.8.88.8.4.4。我们可以尝试连接他们中的任何一个。

主机8.8.8.8的快速Nmap给出了以下结果:

代码语言:javascript
复制
$ sudo nmap 8.8.8.8

Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-14 10:17 IST
Nmap scan report for google-public-dns-a.google.com (8.8.8.8)
Host is up (0.0048s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
53/tcp open  domain

Nmap done: 1 IP address (1 host up) scanned in 23.81 seconds

正如我们所看到的,53/tcp是开放的和非过滤的。如果您是非根用户,请记住使用sudo或Nmap的-Pn参数发送精心编制的探测数据包,并确定主机是否处于运行状态。

在尝试使用Python之前,让我们使用外部工具Netcat来测试连通性:

代码语言:javascript
复制
$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

Netcat确认我们可以通过53/tcp连接到8.8.8.8。现在,我们可以在Python中设置到8.8.8.8:53/tcp的套接字连接,以检查连接:

代码语言:javascript
复制
import socket

def internet(host="8.8.8.8", port=53, timeout=3):
    """
    Host: 8.8.8.8 (google-public-dns-a.google.com)
    OpenPort: 53/tcp
    Service: domain (DNS/TCP)
    """
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except socket.error as ex:
        print(ex)
        return False

internet()

另一种方法是向其中一台服务器发送手动创建的DNS探测,并等待响应。但是,我假设,由于数据包丢失,DNS解析失败等原因,它可能会被证明比较慢。如果你不这么认为,请发表评论。

更新#1:感谢@theamk的评论,timeout现在是一个参数,默认情况下初始化为3s

更新#2:我做了快速测试,以确定这个问题的所有有效答案中最快和最通用的实现。总结如下:

代码语言:javascript
复制
$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.487

iamaziz.py
True
00:00:00:00.335

ivelin.py
True
00:00:00:00.105

jaredb.py
True
00:00:00:00.533

kevinc.py
True
00:00:00:00.295

unutbu.py
True
00:00:00:00.546

7h3rAm.py
True
00:00:00:00.032

再一次:

代码语言:javascript
复制
$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.450

iamaziz.py
True
00:00:00:00.358

ivelin.py
True
00:00:00:00.099

jaredb.py
True
00:00:00:00.585

kevinc.py
True
00:00:00:00.492

unutbu.py
True
00:00:00:00.485

7h3rAm.py
True
00:00:00:00.035

上面输出中的True表示来自各自作者的所有这些实现都正确地识别了到互联网的连接。时间以毫秒分辨率显示。

更新#3:在异常处理更改后再次测试:

代码语言:javascript
复制
defos.py
True
00:00:00:00.410

iamaziz.py
True
00:00:00:00.240

ivelin.py
True
00:00:00:00.109

jaredb.py
True
00:00:00:00.520

kevinc.py
True
00:00:00:00.317

unutbu.py
True
00:00:00:00.436

7h3rAm.py
True
00:00:00:00.030
票数 130
EN

Stack Overflow用户

发布于 2015-04-25 01:52:02

只做一个HEAD请求会更快,这样就不会获取HTML。

此外,我相信google会更喜欢这种方式:)

代码语言:javascript
复制
try:
    import httplib  # python < 3.0
except:
    import http.client as httplib


def have_internet():
    conn = httplib.HTTPSConnection("8.8.8.8", timeout=5)
    try:
        conn.request("HEAD", "/")
        return True
    except Exception:
        return False
    finally:
        conn.close()
票数 80
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3764291

复制
相关文章

相似问题

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