2014-01-03 2 views
15

У меня есть следующий код, который проверяет наличие интернет-соединения.Проверка наличия интернет-соединения в python

import urllib2 

def internet_on(): 
    try: 
     response=urllib2.urlopen('http://74.125.228.100',timeout=20) 
     return True 
    except urllib2.URLError as err: pass 
    return False 

Это проверит подключение к Интернету, но насколько оно эффективно?

Я знаю, что интернет отличается качеством от человека к человеку, поэтому я ищу что-то, что наиболее эффективно для широкого спектра, и приведенный выше код кажется, что могут быть лазейки, где люди могут найти ошибки. Например, если у кого-то было очень медленное соединение и потребовалось больше 20 секунд, чтобы ответить.

+0

Почему? Как уже было сказано, это звучит как простой пример «взглянуть, прежде чем прыгать». Лучший подход обычно «легко просить прощения, чем разрешения.«Если вы объясните, что вы пытаетесь выполнить, вы можете получить более точные ответы. –

+0

@ Jean-PaulCalderone Я пытаюсь убедиться, что у пользователя есть подключение к Интернету, прежде чем моя программа начнет выполнять некоторые задачи, которые будут обновлять систему Например, загружать пакеты из зеркала, а затем устанавливать их. –

+2

Почему бы вам просто не попробовать загрузить эти пакеты? Если попытка подключения к зеркалу отключается, вы можете сообщить о тайм-ауте для пользователя. * предпочитайте этот опыт для вашей неудачной попытки обнаружить, работает ли их сеть. –

ответ

30

Мой подход был бы что-то вроде этого:

import socket 
REMOTE_SERVER = "www.google.com" 
def is_connected(hostname): 
    try: 
    # see if we can resolve the host name -- tells us if there is 
    # a DNS listening 
    host = socket.gethostbyname(hostname) 
    # connect to the host -- tells us if the host is actually 
    # reachable 
    s = socket.create_connection((host, 80), 2) 
    return True 
    except: 
    pass 
    return False 
%timeit is_connected(REMOTE_SERVER) 
> 10 loops, best of 3: 42.2 ms per loop 

Это будет возвращать в течение менее чем за секунду, если нет подключения (OSX, Python 2.7).

Примечание: этот тест может возвращать ложные срабатывания - например. поиск DNS может вернуть сервер в локальной сети. Чтобы быть уверенным, что вы подключены к Интернету и разговариваете с действующим хостом, обязательно используйте более сложные методы (например, SSL).

+0

Это похоже на лучший подход. –

+2

Что делать, если пользователь добавил www.google.com в свой файл/etc/hosts? Что делать, если они используют локальный кеширующий сервер имен или находятся в локальной сети с кеширующим сервером имен поблизости? Что делать, если они «подключены к Интернету», но трафик фактически не маршрутизируется должным образом? Есть много путей для этого, чтобы потерпеть неудачу. –

+1

@ Жан-Поль Калдерон справедливая точка, включала фактическое испытание соединения и соответствующий комментарий. Не стесняйтесь улучшать ответ, если видите нужное – miraculixx

-2

Увеличение таймаута до 30 секунд? Сделайте несколько попыток? Попробуйте несколько хостов?

+0

Ну, я как бы надеялся, что у кого-то может быть другой код, который лучше работал или имел бы лучшую проверку ошибок. У меня есть только несколько человек, которые могут проверить мои программное обеспечение, поэтому, если проблема не отображается с ними, это может быть очень неудобно для меня. Я могу увеличить таймаут, но есть люди, у которых есть странные подключения, которые могут отправлять запросы ts, но не может слышать от них, поэтому я хочу оставить тайм-аут еще немного низким ... –

0

Http кажется слишком высоким уровнем для проверки доступности сети.

Тем не менее вы можете создать поток, который периодически проверяет подключение и сохраняет состояние подключения, а затем метод internet_on может просто проверять сохраненное состояние. Это будет быстрее, чем тестирование соединения каждый раз.

+0

Нужно только проверять подключение один раз, прямо при его запуске. –

1

это будет работать

import urllib 
try : 
    stri = "https://www.google.co.in" 
    data = urllib.urlopen(stri) 
    print "Connected" 
except e: 
    print "not connected" ,e 
+0

Это плохо! Потому что вы загружаете всю страницу! Вам это не нужно! – Ievgen

-1

Это то, что я использую:

import subprocess 

subprocess.call('ping -t 8.8.8.8') 
+0

не будет работать на Linux – kmonsoor

1

Я хотел проверить мое подключение к Интернету в бесконечном цикле, чтобы контролировать, когда моя сеть идет вверх и вниз. Я заметил следующее: когда моя сеть была отключена, и я начал сценарий мониторинга, как это, и сеть вернулась, сценарий этого не заметил. Сеть была жива, но сценарий этого не видел. Когда моя сеть была включена, и я начал этот сценарий, он заметил изменения. Поэтому я придумал следующее решение, которое работало для меня в обоих случаях:

import shlex 
from subprocess import call, PIPE, STDOUT 

def get_return_code_of_simple_cmd(cmd, stderr=STDOUT): 
    """Execute a simple external command and return its exit status.""" 
    args = shlex.split(cmd) 
    return call(args, stdout=PIPE, stderr=stderr) 

def is_network_alive(): 
    cmd = "ping -c 1 www.google.com" 
    return get_return_code_of_simple_cmd(cmd) == 0 

Здесь мы опираемся на внешнюю программу (ping), который не зависит от нашего сценария.

0

Надеюсь, я могу помочь с проблемой.

import urllib 
try : 
    url = "https://www.google.com" 
    urllib.urlopen(url) 
    status = "Connected" 
except : 
    status = "Not connect" 
print status 
5

На Python 2.6 и выше (включая Python 3), более простое решение, которое также совместимо с IPv6 будет

import socket 


def is_connected(): 
    try: 
     # connect to the host -- tells us if the host is actually 
     # reachable 
     socket.create_connection(("www.google.com", 80)) 
     return True 
    except OSError: 
     pass 
    return False 

Это разрешает имя и пытается соединиться друг с обратными Адресная перед заключением он не работает. Это также включает адреса IPv6.

+0

Спасибо за это решение – Ievgen

Смежные вопросы