request def connect(host='http://google.com'): try: urllib. request. urlopen(host) #Python 3. x return True except: return False # test print( "connected" if connect() else "no internet!" )
Select the Start button, then type settings. Select Settings > Network & internet. The status of your network connection will appear at the top. Windows 10 lets you quickly check your network connection status.
Perhaps you could use something like this:
import urllib2
def internet_on():
try:
urllib2.urlopen('http://216.58.192.142', timeout=1)
return True
except urllib2.URLError as err:
return False
Currently, 216.58.192.142 is one of the IP addresses for google.com. Change http://216.58.192.142
to whatever site can be expected to respond quickly.
This fixed IP will not map to google.com forever. So this code is not robust -- it will need constant maintenance to keep it working.
The reason why the code above uses a fixed IP address instead of fully qualified domain name (FQDN) is because a FQDN would require a DNS lookup. When the machine does not have a working internet connection, the DNS lookup itself may block the call to urllib_request.urlopen
for more than a second. Thanks to @rzetterberg for pointing this out.
If the fixed IP address above is not working, you can find a current IP address for google.com (on unix) by running
% dig google.com +trace
...
google.com. 300 IN A 216.58.192.142
If we can connect to some Internet server, then we indeed have connectivity. However, for the fastest and most reliable approach, all solutions should comply with the following requirements, at the very least:
To comply with these, one approach could be to, check if one of the Google's public DNS servers is reachable. The IPv4 addresses for these servers are 8.8.8.8
and 8.8.4.4
. We can try connecting to any of them.
A quick Nmap of the host 8.8.8.8
gave below result:
$ 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
As we can see, 53/tcp
is open and non-filtered. If you are a non-root user, remember to use sudo
or the -Pn
argument for Nmap to send crafted probe packets and determine if a host is up.
Before we try with Python, let's test connectivity using an external tool, Netcat:
$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
Netcat confirms that we can reach 8.8.8.8
over 53/tcp
. Now we can set up a socket connection to 8.8.8.8:53/tcp
in Python to check connection:
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()
Another approach could be to send a manually crafted DNS probe to one of these servers and wait for a response. But, I assume, it might prove slower in comparison due to packet drops, DNS resolution failure, etc. Please comment if you think otherwise.
UPDATE #1: Thanks to @theamk's comment, timeout is now an argument and initialized to 3s
by default.
UPDATE #2: I did quick tests to identify the fastest and most generic implementation of all valid answers to this question. Here's the summary:
$ 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
And once more:
$ 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
in the above output signifies that all these implementations from respective authors correctly identify connectivity to the Internet. Time is shown with milliseconds resolution.
UPDATE #3: Tested again after the exception handling change:
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
It will be faster to just make a HEAD request so no HTML will be fetched.
Also I am sure google would like it better this way :)
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()
As an alternative to ubutnu's/Kevin C answers, I use the requests
package like this:
import requests
def connected_to_internet(url='http://www.google.com/', timeout=5):
try:
_ = requests.head(url, timeout=timeout)
return True
except requests.ConnectionError:
print("No internet connection available.")
return False
Bonus: this can be extended to this function that pings a website.
def web_site_online(url='http://www.google.com/', timeout=5):
try:
req = requests.head(url, timeout=timeout)
# HTTP errors are not raised by default, this statement does that
req.raise_for_status()
return True
except requests.HTTPError as e:
print("Checking internet connection failed, status code {0}.".format(
e.response.status_code))
except requests.ConnectionError:
print("No internet connection available.")
return False
Just to update what unutbu said for new code in Python 3.2
def check_connectivity(reference):
try:
urllib.request.urlopen(reference, timeout=1)
return True
except urllib.request.URLError:
return False
And, just to note, the input here (reference) is the url that you want to check: I suggest choosing something that connects fast where you live -- i.e. I live in South Korea, so I would probably set reference to http://www.naver.com.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With