域名系统(DNS)是一个分布式的数据库,它主要用来把主机名转换成IP地址。
DNS系统之所以存在主要是因为方便用户记忆和更改IP地址不影响域名。
4.1 进行DNS查询
DNS提供一系列的提名回答,每个提名给出一个更详细的答案,直到获得最终答案。
作为一个例子,让我们来看一下查询www.external.example.com。首先,您的程序会和操作系统配置文件指定的本地名称服务器通信。这个服务器是一个递归的名称服务器, 它收到请求并以适当的方式传递下去。
递归服务器要做的第一件事就是访问.com域。后者有个内置的顶级域名列表,这些服务器可以分发世界上顶级域名的信息,例如.com。
对于.com的回答是以一种指向另一个名称服务器的提名形式给出的。这个名称服务器可以提供名称中包含.com的信息。所以,查询会发送到这个服务器。该.com服务器以另一个提名回答作为回应,这个提名回答指向一个可以提供example.com的名称信息。
这个循环重复多次,直到最终查询到达为external.example.com服务的名称服务器。这个服务器知道问题中的IP地址,并返回它。
4.2 使用操作系统查询服务
操作系统提供了一套用于DNS查询的服务。
当您使用操作系统的查找服务时,Unix系统会先去查找本地DNS缓存,缓存保存在/etc/hosts文件中。如果未能查找到,就会发送请求给本地DNS服务器,本地服务器会返回给您IP地址。所有这些细节您都不知道,操作系统会自动查询。
4.2.1 执行基本查询
最基本的查询是正向查询,它根据一个主机名来查找一个IP地址。
您或许回想自己实现DNS查询的操作,因为查询DNS确实复杂化了,变得简单点,程序会运行的更好。这在要多次连接某个服务器的时候,非常有用。在Python中,提供了函数:
getaddrinfo(host, port [, family[, socktype[,proto[, flags]]]])
返回值是一个tuple:
(family, socktype, proto, canonname, sockaddr)
sockaddr实际上就是远程机器的地址,是您进行查找的时候要找的数据。
如果您只是想得到一个简单的IP地址来连接,您可以选择列表中的第一个tuple。这里有个:
#!/usr/bin/env python3
#Basic getaddrinfo() basic example - Chapter 4 - getaddrinfo-basic.py
import sys, socket
result = socket.getaddrinfo(sys.argv[1],None)
print(