Interactuar con servicios de nombres de dominio

Las aplicaciones usan la red para comunicarse con los servidores para operaciones de servicio de nombres de dominio (DNS) como la conversión entre nombres de host y direcciones IP. asyncio tiene métodos de conveniencia en el bucle de eventos para ejecutar esas operaciones en segundo plano, para evitar el bloqueo durante las consultas.

Búsqueda de dirección por nombre

Usa la co-rutina getaddrinfo() para convertir un nombre de host y un número de puerto a una dirección IP o IPv6. Al igual que con la versión de la función en el módulo socket, el valor de retorno es una lista de tuplas que contienen cinco piezas de información.

  1. La familia de direcciones
  2. El tipo de dirección
  3. El protocolo
  4. El nombre canónico para el servidor.
  5. Una tupla de dirección de conector adecuada para abrir una conexión al servidor en el puerto originalmente especificado

Las consultas se pueden filtrar por protocolo, como en este ejemplo, donde solo se devuelven las respuestas TCP.

asyncio_getaddrinfo.py
import asyncio
import logging
import socket
import sys


TARGETS = [
    ('pymotw.com', 'https'),
    ('doughellmann.com', 'https'),
    ('python.org', 'https'),
]


async def main(loop, targets):
    for target in targets:
        info = await loop.getaddrinfo(
            *target,
            proto=socket.IPPROTO_TCP,
        )

        for host in info:
            print('{:20}: {}'.format(target[0], host[4][0]))


event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop, TARGETS))
finally:
    event_loop.close()

El programa de ejemplo convierte un nombre de host y un nombre de protocolo a dirección IP y número de puerto.

$ python3 asyncio_getaddrinfo.py

pymotw.com          : 66.33.211.242
doughellmann.com    : 66.33.211.240
python.org          : 23.253.135.79
python.org          : 2001:4802:7901::e60a:1375:0:6

Búsqueda de nombre por dirección

La co-rutina getnameinfo() trabaja en la dirección inversa, convierte una dirección IP a un nombre de host y un número de puerto a un nombre de protocolo, donde sea posible.

asyncio_getnameinfo.py
import asyncio
import logging
import socket
import sys


TARGETS = [
    ('66.33.211.242', 443),
    ('104.130.43.121', 443),
]


async def main(loop, targets):
    for target in targets:
        info = await loop.getnameinfo(target)
        print('{:15}: {} {}'.format(target[0], *info))


event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop, TARGETS))
finally:
    event_loop.close()

Este ejemplo muestra que la dirección IP para pymotw.com se refiere a una servidor en DreamHost, la empresa de alojamiento donde se ejecuta el sitio. La segunda dirección IP examinada es para python.org, y no resuelve de nuevo a un nombre de host.

$ python3 asyncio_getnameinfo.py

66.33.211.242  : apache2-echo.catalina.dreamhost.com https
104.130.43.121 : 104.130.43.121 https

Ver también

  • La discusión del módulo socket incluye un examen más detallado de estas operaciones.