asyncio之域名服务交互
应用程序使用网络与服务器进行通信时可能需要域名服务(DNS),如在主机名和IP地址之间进行转换。asyncio事件循环有方便的方法在后台进行处理,以避免在查询时阻塞。
根据域名查找地址
使用getaddrinfo()协程方法将主机名和端口号转换成IP或IPv6地址。和在socket模块中的方法版本一样,返回值是一个包含五个信息的tuple列表。
- 地址族
- 地址类型
- 协议
- 服务器的规范名称
- 套接字地址元组适用于打开原始指定的端口上的服务器连接
查询可以通过协议进行过滤,在这个例子中,只返回TCP的响应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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 21 22
| 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()
|
这个例子显示从域名公司DreamHost的服务器返回了pymotw.com的IP地址。第二个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
|
原文地址