python проверить, подключен ли хост к сети

Я нашел вариант, обсуждаемый здесь, который отлично работает, если хост подключен к сети. Однако socket.gethostbyname(hostname) долгое время зависает, если хост не подключен.

Я видел предложение запустить socket.gethostbyname(hostname) в потоке, и если этот поток не возвратил результат за указанный период, предположим, что он не подключен. Я подумал, что это хорошая идея, но я недостаточно разбираюсь в потоках (хотя я использовал их успешно), чтобы знать, как это сделать.

Я нашел это обсуждение Как найти время выполнения потока в Python, который, по-видимому, подразумевает, что это не тривиально. Есть идеи? Благодарю.

Редактировать:

Я должен признать свое невежество. Я не понял (хотя должен был), что socket.gethostbyname(hostname) выполняет поиск DNS. Итак, я собрал это просто, чтобы проверить подключение сокета к интересующему узлу на порту 22:

 #! /usr/bin/python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(0.5) try: s.connect(('192.168.2.5',22)) except Exception, e: print 'connection failed' s.close() 

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

Сначала этот скрипт проверяет подключение к сети, если соединение обнаружено, то он проверяет наличие определенного хоста в этой сети:

 #! /usr/bin/python import socket import fcntl import struct def check_connection(): ifaces = ['eth0','wlan0'] connected = [] i = 0 for ifname in ifaces: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15]) )[20:24]) connected.append(ifname) print "%s is connected" % ifname except: print "%s is not connected" % ifname i += 1 return connected connected_ifaces = check_connection() if len(connected_ifaces) == 0: print 'not connected to any network' else: print 'connected to a network using the following interface(s):' for x in connected_ifaces: print '\t%s' % x s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(0.5) try: s.connect(('192.168.2.5',22)) print 'connected to hostname' except Exception, e: print 'connection to hostname failed' s.close() 

2 Solutions collect form web for “python проверить, подключен ли хост к сети”

Есть хороший шанс, что блокирующий вызов gethostbyname самом деле не нужен здесь.

Во-первых, вы можете вообще не искать DNS-поиск, и почти все, что вы можете делать с сокетами, например, connect -already обрабатывает таймауты.

Во-вторых, если вам действительно нужны тайм-ауты в поиске DNS, вы, вероятно, захотите использовать асинхронную DNS-библиотеку, такую ​​как pycares .

Но если вам понадобятся тайм-ауты в поиске DNS, и вы не можете полагаться на внешний код, тогда вы правы, вам придется запускать поиск DNS в другом потоке и ждать его в основном потоке.

Итак, как вы это делаете?

Ну, вы можете join к потоку с таймаутом. Или вы можете подождать Condition или Event которые может подавать фоновый поток, или, при select , на pipe , к которой может писать фоновый поток.

Простейшая вещь, вероятно, join с таймаутом … за исключением того, что вы в конечном итоге оставляете фоновый поток, запущенный после таймаута, и если вы попытаетесь выйти до его завершения, Python может (и будет, с CPython 2.7 или 3.3 на большинстве основных платформ) подождите, пока он закончит, прежде чем уйти. Способ исправления заключается в использовании потока daemon , но тогда вы не можете законно join нему. Вы можете демонировать его после таймаута, но я думаю, что здесь Event проще.

Так, например:

 event = threading.Event() def blocking_dns(): socket.gethostbyname(host) event.set() thread = threading.Thread(target=blocking_dns) thread.daemon = True thread.start() success = event.wait(timeout) 

Вот универсальная обертка:

 def run_with_timeout(timeout, func, *args, **kwargs): event = threading.Event() def wrapper(): func(*args, **kwargs) event.set() thread = threading.Thread(target=wrapper, args=args, kwargs=kwargs) thread.daemon = True thread.start() return event.wait(timeout) 

Что вы можете использовать следующим образом:

 dns_works = run_with_timeout(5.0, socket.gethostbyname, 'www.google.com') 

Использование Event для чего-либо менее тривиального, чем это становится сложным (и часто вы не можете видеть, что это сложно, и писать код, который работает 99% времени и невозможно отладить другие 1%). Обычная проблема заключается в том, что вы можете пропустить set из фонового потока. Если вас не волнует, произойдет ли это до того, как вы проверили, или только после того, как вы начали ждать, вы можете использовать Event ; в противном случае вам нужно Condition .

если вы находитесь в системе Windows, вы можете использовать это

 x = os.system("ping -n 1 google.com") if x == 0: print "HOST IS CONNECTED :) " 
  • Не удается привязать адрес после сбоев программы сокета
  • Преобразуйте шестнадцатеричную строку «little endian» в IP-адрес в Python
  • Отправить изображение через сокет в виде двоичных данных
  • ipsec.py CANT НАЙДИТЕ атрибут IPPROTO_ESP и socket.IPPROTO_AH
  • Производительность S / Python Socket?
  • Скребок Python - ошибка Socket прерывает скрипт, если цель равна 404'd
  • Извлечение полученных данных в сокет tcp в Python
  • многопоточный сервер python
  • Python - лучший язык программирования в мире.