zoukankan      html  css  js  c++  java
  • python 网络编程(五)---DNS域名系统

    1.域名系统定义

    DNS计算机域名系统由域名服务器和域名解析器组成。通常输入的是网址就是一个域名。

    image

    2.域名查询

    查询方式包括:

    1)正向查询:由域名查找对应的IP(如:www.baidu.com—>119.75.218.77

    2)反向查询:由IP查找域名(如:119.75.218.77 –> www.baidu.com

    查询方式包括:

    1)递归查询:当DNS服务器接收到客户端的查询请求时,会做出相应的反应(本地DNS服务器查询、其他服务器查询)(主要发生在客户端与DNS服务器端)

    2)迭代查询:这一部分是对收到的客户端请求做出反应。首先会在本地DNS服务器缓存中进行查询数据,如果查询到对应的ip则进行返回给客户端。否则,返回一个指针,指向下一级的DNS服务器,继续该过程直到找到所查名字的DNS服务器。

    查询过程:

    以正向查询为例:

    当客户端程序要通过一个主机名称来访问网络中的一台主机时,它首先要得到这个主机名称所对应的IP地址,因为IP数据报中允许放置的是目地主机的IP地址,而不是主机名称。

    image

    步骤:

    1)客户端向本地DNS服务器查询 www.redhat.com,(递归查询)

    2)本地DNS服务器检查区域数据库,由于服务器没有查询到www.redhat.com 于是它将查询请求传递给跟服务器(“.”DNS服务器),请求解析主机名称。根名称服务器把“com”DNS服务器IP返回给本地服务器,(迭代)

    3)本地DNS服务器将请求发给“com”DNS服务器,该服务器根据请求将“redhat.com”DNS服务器IP地址返回给本地DNS服务器(迭代查询)。

    4)本地DNS服务器向“redhat.com”DNS服务器发送请求,由于该服务器具有“www.redhat.com”记录,它将www.redhat.com的IP地址返回给本地DNS服务器。

    5)本地DNS服务器将www.redhat.com的IP地址发送给客户端。

    3.示例:

    正向查询函数:Getaddrinfo(host,port[,family[,sockettype[,proto[,flags]]]])

    参数host为域名,以字符串形式给出代表一个IPV4/IPV6地址或者None.  

    参数port如果字符串形式就代表一个服务名,比如“http”"ftp""email"等,或者为数字,或者为None  

    参数family为地主族,可以为AF_INET  ,AF_INET6 ,AF_UNIX.  

    参数socketype可以为SOCK_STREAM(TCP)或者SOCK_DGRAM(UDP)  

    参数proto通常为0可以直接忽略  

    参数flags为AI_*的组合,比如AI_NUMERICHOST,它会影响函数的返回值 

    该函数返回值是一列tuple,每一个tuple如下:

    (family,socktype,proto,canonname,sockaddr)

    其中sockaddr实际上就是远程机器的地址和端口,也就是查询的数据。

    import socket
    host=raw_input('host:')
    result=socket.getaddrinfo(host,None)
    counter=0
    for i in result:
        print "%-2d:%s"%(counter,i) 
        counter+=1
    raw_input('Press ENTER')

    结果:

    image

    为什么一个域名有多个IP?

    反向查询函数:gethostbyaddr(addr,len,type)

    gethostbyaddr(addr,len,type) 

    参数addr可以为IPv4或IPv6的IP地址,参数len为参数addr的长度,参数type为AF_INET。

    import socket
    hostip=raw_input('ip:')
    try:
        result=socket.gethostbyaddr(hostip)
        print "hostname:"+result[0]
        print "
     Addresses:"
        for i in result[2]:
            print " " +i
    except socket.herror, e:
        print "counld not look up name:",e

    image

    使用PyDNS进行高级查询

    pyDNS提供了一个功能更强的访问DNS系统的接口。其下载地址为http://pydns.sourceforge.net

    首先调用DNS.DiscoverNameServers()查找系统中的名称服务器。然后建立一个请求对象DNS.Request()。DNS.Request()的req()方法用来执行实际的查询。通常有两个参数:name给出了实际查询的名称;qtype指定了record类型。当使用请求对象来发出查询请求时,pyDNS会返回一个包含结果的应答对象(answer object),该对象有个属性叫answers,包含所有返回的应答列表。

    import DNS
    query=raw_input('输入DNS:')
    DNS.DiscoverNameServers()
    
    reqobj=DNS.Request()
    answerobj=reqobj.req(name=query,qtype=DNS.Type.ANY)
    if not len(answerobj.answers):
        print "Not found"
    for i in answerobj.answers:
        print "%-5s %s"%(i['typename'],i['data'])

    这个包功能非常强大,在此不细说了。

    参考:http://www.jinlie.net/?p=638 

           http://www.cnblogs.com/xiaowuyi/archive/2012/08/20/2646725.html

  • 相关阅读:
    【前缀和】【枚举倍数】 Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) D. Arpa and a list of numbers
    【推导】【暴力】Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) C. Five Dimensional Points
    【推导】Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017) B. Arpa and an exam about geometry
    【推导】【模拟】AtCoder Regular Contest 082 F
    【计算几何】【推导】【补集转化】AtCoder Regular Contest 082 E
    【推导】AtCoder Regular Contest 082 D
    【推导】【分类讨论】Codeforces Round #431 (Div. 1) B. Rooter's Song
    【推导】【贪心】Codeforces Round #431 (Div. 1) A. From Y to Y
    【贪心】hdu6180 Schedule
    【启发式搜索】【A*算法】hdu6171 Admiral
  • 原文地址:https://www.cnblogs.com/menghuizuotian/p/3765557.html
Copyright © 2011-2022 走看看