tutorialspoint socket programming network gui español book python networking

python - socket - Comprobando la conexión de red



socket python 3 español (13)

Como alternativa a las respuestas de ubutnu / Kevin C, utilizo el paquete de requests esta manera:

import requests def connected_to_internet(url=''http://www.google.com/'', timeout=5): try: _ = requests.get(url, timeout=timeout) return True except requests.ConnectionError: print("No internet connection available.") return False

Bonificación: esto se puede extender a esta función que hace ping a un sitio web.

def web_site_online(url=''http://www.google.com/'', timeout=5): try: req = requests.get(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

Quiero ver si puedo acceder a una API en línea, pero para eso necesito tener acceso a Internet.

¿Cómo puedo ver si hay una conexión disponible y activa usando Python?


Esto podría no funcionar si el localhost ha sido cambiado desde 127.0.0.1 Prueba

import socket ipaddress=socket.gethostbyname(socket.gethostname()) if ipaddress=="127.0.0.1": print("You are not connected to the internet!") else: print("You are connected to the internet with the IP address of "+ ipaddress )

A menos que se edite, la IP de su computadora será 127.0.0.1 cuando no esté conectada a Internet. Este código básicamente obtiene la dirección IP y luego pregunta si es la dirección IP del host local. Espero que ayude


La mejor forma de hacerlo es hacer que contrasta con una dirección IP que python siempre proporciona si no puede encontrar el sitio web. En este caso, este es mi código:

import socket print("website connection checker") while True: website = input("please input website: ") print("") print(socket.gethostbyname(website)) if socket.gethostbyname(website) == "92.242.140.2": print("Website could be experiencing an issue/Doesn''t exist") else: socket.gethostbyname(website) print("Website is operational!") print("")


Pruebe la operación que estaba intentando hacer de todos modos. Si falla, python debería lanzarte una excepción para avisarte.

Intentar alguna operación trivial primero para detectar una conexión introducirá una condición de carrera. ¿Qué ocurre si la conexión a Internet es válida cuando realiza la prueba, pero baja antes de que necesite realizar el trabajo real?


Será más rápido hacer una solicitud HEAD para que no se obtenga HTML.
También estoy seguro de que Google lo preferiría así :)

try: import httplib except: import http.client as httplib def have_internet(): conn = httplib.HTTPConnection("www.google.com", timeout=5) try: conn.request("HEAD", "/") conn.close() return True except: conn.close() return False


Si podemos conectarnos a algún servidor de Internet, entonces sí tenemos conectividad. Sin embargo, para el enfoque más rápido y confiable, todas las soluciones deben cumplir con los siguientes requisitos, como mínimo:

  • Evite la resolución de DNS (necesitaremos una IP que sea conocida y garantizada para estar disponible la mayor parte del tiempo)
  • Evite las conexiones basadas en la capa de aplicación (conectándose a un servicio HTTP / FTP / IMAP)
  • Evite las llamadas a servicios externos desde Python u otro idioma de elección (tenemos que encontrar una solución independiente del idioma que no dependa de soluciones de terceros)

Para cumplir con esto, un enfoque podría ser verificar si uno de los servidores DNS públicos de Google es accesible. Las direcciones IPv4 para estos servidores son 8.8.8.8 y 8.8.4.4 . Podemos intentar conectarnos con cualquiera de ellos.

Un Nmap rápido del host 8.8.8.8 dio el siguiente resultado:

$ 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

Como podemos ver, TCP / 53 está abierto y no filtrado. Si usted no es un usuario root, recuerde usar sudo o el argumento -Pn para que Nmap envíe paquetes de prueba diseñados y determine si el host está activo.

Antes de intentar con Python, probemos la conectividad usando una herramienta externa, Netcat:

$ nc 8.8.8.8 53 -zv Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

Netcat confirma que podemos alcanzar 8.8.8.8 sobre TCP / 53. Ahora podemos configurar una conexión de socket a 8.8.8.8:53/TCP en Python para verificar la conexión:

>>> 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 Exception as ex: ... print ex.message ... return False ... >>> internet() True >>>

Otro enfoque podría ser enviar una sonda de DNS manual a uno de estos servidores y esperar la respuesta. Pero, supongo, podría ser más lento en comparación debido a caídas de paquetes, fallas en la resolución de DNS, etc. Comente si piensa lo contrario.

ACTUALIZACIÓN # 1: Gracias al comentario de @ theamk, el tiempo de espera ahora es un argumento y se inicializa a 3s por defecto.

ACTUALIZACIÓN # 2: Hice pruebas rápidas para identificar la implementación más rápida y más genérica de todas las respuestas válidas a esta pregunta. Aquí está el resumen:

$ 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

Y una vez más:

$ 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 en el resultado anterior significa que todas estas implementaciones de los respectivos autores identifican correctamente la conectividad a Internet. El tiempo se muestra con una resolución de milisegundos.

ACTUALIZACIÓN # 3: Probado de nuevo después del cambio de manejo de excepciones:

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


Simplemente puede tratar de descargar datos, y si falla la conexión sabrá que algo con conexión no está bien.

Básicamente no puede verificar si la computadora está conectada a internet. Puede haber muchas razones para fallas, como configuración de DNS incorrecta, firewalls, NAT. Incluso si realiza algunas pruebas, no puede garantizar que tendrá conexión con su API hasta que lo intente.


Solo para actualizar lo que dijo unutbu para el nuevo código en Python 3.2

def check_connectivity(reference): try: urllib.request.urlopen(reference, timeout=1) return True except urllib.request.URLError: return False

Y, solo para observar, la entrada aquí (referencia) es la url que desea verificar: sugiero que elija algo que se conecte rápidamente en su lugar de residencia, es decir, vivo en Corea del Sur, por lo que probablemente haga referencia a http: / / www.naver.com .


Tal vez podrías usar algo como esto:

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

Actualmente, 216.58.192.142 es una de las direcciones IP para google.com. Cambie http://216.58.192.142 a cualquier sitio que se pueda esperar que responda rápidamente .

Esta IP fija no se correlacionará con google.com para siempre. Por lo tanto, este código no es robusto; necesitará mantenimiento constante para que siga funcionando.

La razón por la que el código anterior utiliza una dirección IP fija en lugar del nombre de dominio completo (FQDN) es porque un FQDN requeriría una búsqueda de DNS. Cuando la máquina no tiene una conexión a Internet que funcione, la búsqueda de DNS puede bloquear la llamada a urllib_request.urlopen por más de un segundo. Gracias a @rzetterberg por señalar esto.

Si la dirección IP fija anterior no funciona, puede encontrar una dirección IP actual para google.com (en Unix) ejecutando

% dig google.com +trace ... google.com. 300 IN A 216.58.192.142


Tomando la respuesta de Six, creo que podríamos simplificar de alguna manera, una cuestión importante ya que los recién llegados se pierden en cuestiones altamente técnicas.

Aquí lo que finalmente utilizaré para esperar a que mi conexión (3G, lenta) se establezca una vez al día para mi monitoreo PV.

Funciona bajo Pyth3 con Raspbian 3.4.2

from urllib.request import urlopen from time import sleep urltotest=http://www.lsdx.eu # my own web page nboftrials=0 answer=''NO'' while answer==''NO'' and nboftrials<10: try: urlopen(urltotest) answer=''YES'' except: essai=''NO'' nboftrials+=1 sleep(30)

Máxima ejecución: 5 minutos si lo alcanzo lo intentaré en una hora, ¡pero es otro guión!


Tomando la respuesta de unutbu como punto de partida, y habiendo sido quemado en el pasado por una dirección de IP "estática" cambiante, hice una clase simple que verifica una vez usando una búsqueda de DNS (es decir, usando la URL " https: // www .google.com "), y luego almacena la dirección IP del servidor que responde para su uso en controles posteriores. De esta forma, la dirección IP siempre estará actualizada (suponiendo que la clase se reinicialice al menos una vez cada tantos años). También doy crédito a gawry por esta respuesta , que me mostró cómo obtener la dirección IP del servidor (después de cualquier redirección, etc.). Por favor, ignore el aparente hackiness de esta solución, voy por un ejemplo de trabajo mínimo aquí. :)

Esto es lo que tengo:

import socket try: from urllib2 import urlopen, URLError from urlparse import urlparse except ImportError: # Python 3 from urllib.parse import urlparse from urllib.request import urlopen, URLError class InternetChecker(object): conn_url = ''https://www.google.com/'' def __init__(self): pass def test_internet(self): try: data = urlopen(self.conn_url, timeout=5) except URLError: return False try: host = data.fp._sock.fp._sock.getpeername() except AttributeError: # Python 3 host = data.fp.raw._sock.getpeername() # Ensure conn_url is an IPv4 address otherwise future queries will fail self.conn_url = ''http://'' + (host[0] if len(host) == 2 else socket.gethostbyname(urlparse(data.geturl()).hostname)) return True # Usage example checker = InternetChecker() checker.test_internet()


mi favorito, al ejecutar scripts en un clúster o no

import subprocess def online(timeout): try: return subprocess.run([''wget'', ''-q'', ''--spider'', ''google.com''], timeout=timeout).returncode == 0 except subprocess.TimeoutExpired: return False

esto ejecuta wget silenciosamente, no descarga nada sino que comprueba que el archivo remoto dado existe en la web


import urllib def connected(host=''http://google.com''): try: urllib.urlopen(host) return True except: return False # test print( ''connected'' if connected() else ''no internet!'' )

Para python 3, use urllib.request.urlopen(host)