asyncio之与DNS服务进行交互

DNS服务进行交互

应用程序使用网络与服务器通信以进行域名服务(DNS)操作,例如在主机名和IP地址之间进行转换。asyncio在事件循环上有方便的方法来处理后台的这些操作,以避免在查询过程中被阻塞。

按名称查询地址

使用协程getaddrinfo()将主机名和端口号转换为IP或IPv6地址。与socket模块中函数的版本一样,返回值是包含五条信息的元组列表。

  • 1.地址家族
  • 2.地址类型
  • 3.协议
  • 4.服务器的规范名称
  • 5.一个socket地址元组,适用于在最初指定的端口上打开到服务器的连接
    查询可以按协议进行过滤,如本示例中所示,只返回TCP响应。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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()

示例程序将主机名和协议名称转换为IP地址和端口号。

1
2
3
4
5
6
$ 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

按地址查询名称

协程getnameinfo()工作方向则相反,在可能的情况下将IP地址转换为主机名和端口号为协议名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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()

此示例显示pymotw.com的IP地址是位于运行站点的托管公司DreamHost上的服务器。查询的第二个IP地址是python.org,它不会解析回主机名。

1
2
3
4
$ python3 asyncio_getnameinfo.py
66.33.211.242 : apache2-echo.catalina.dreamhost.com https
104.130.43.121 : 104.130.43.121 https

本文翻译自《The Python3 Standard Library By Example》asyncio相关章节

文章目录
  1. 1. 按名称查询地址
  2. 2. 按地址查询名称
|