zoukankan      html  css  js  c++  java
  • 《Python网络编程基础》第四章 域名系统

    域名系统(DNS) 是一个分布式的数据库,它主要用来把主机名转换成IP地址。DNS以及相关系统之所以存在,主要有以下两个原因:

     
    • 它们可以使人们比较容易地记住名字,如www.baidu.com。
    • 它们允许服务器改变IP地址,但是还用同样的名字。
     
     
     
    作为一个例子,让我们看一下查询    www.baidu.com  首先,您的程序会和操作系统配置文件指定的本地名称服务器通信。这个服务器是一个递归的名称服务器,它收到请求并以适当的方式传递下去,它会为您完成大量工作。
     
         递归服务器做的第一件事情是询问.com域。后者有个内置的顶级域名列表,这些服务器可以分发世界上顶级域名的信息,例如.com
     
        
     
     
         这个循环重复多次,直到最终查询到达www.baidu.com服务的名称服务器。这个服务器知道问题中的IP地址,并返回它。
     
         
     
     
    使用操作系统查询服务
         操作系统本身带一些用于DNS查找的功能(经常被称为resolver库)。
     
     
     
    执行基本查询
     
         最基本的查询是正向查询,它根据一个主机名来查找IP地址。例如你想从www.baidu.com上下载一个Web页面。首先您需要找到IP地址。
     
         在Python中,您将用到的函数是socket.getaddrinfo(),
     
     
     
         sockaddr实际上就是远程机器的地址。
     
         这里的值是以tuple的形式打印出来的。
     
     
     
     
     
    通过getaddrinfo()获得全部的条目也是可以的。
     
     
     
    import sys,socket



    result = socket.getaddrinfo(sys.argv[1],None)

    counter = 0

    for item in result:
        print "%-2d: %s" % (counter,item[4])
        counter += 1


    注意:同一条目在您的机器上也许不会显示多次。在某些平台上,例如Windows的getaddrinfo()默认只支持一种协议。即使在支持多协议的平台上,如果有些协议没有配置,也会只有一个结果。为了限制结果,让每个条目只显示一次,您需要为protocol参数设定socket.SOCK_STREAM为family参数设定0,让它支持所有family
     
     
     
     
     
    这里有一个上个例子的更好的版本:
     
         import sys,socket


    result = socket.getaddrinfo(sys.argv[1],None,0,socket.SOCK_STREAM)


    counter = 0

    for item in result:
        print "%-2d: %s" % (counter,item[4])
        counter += 1




    这一次,您将看到每一个条目只显示一次。
     
     
     
     
     
    执行反向查询
     
         
     
     
     
    反向查找基础
     
         有一个重要的问题需要您明白,那就是,对于一个IP地址,完全有可能不存在反向的映射。事实上,很多IP地址根本就没有对应的域名。所以,您需要确保为每一个反向查找的行为捕获和处理socket.herror()。
     
     
    import sys,socket



    try:
        # Perform the lookup
        result = socket.gethostbyaddr(sys.argv[1])


        print "Primary hostname:"
        print "  " + result[0]



        print " Addresses:"
        for item in result[2]:
            print " " + item

    except socket.herror, e:
        print "Couldn't  look up name:", e



     
     
     
     
     
    对于反向查询,授权是基于IP地址的。
     
     
     
     
     
    import sys,socket

    def getipaddrs(hostname):
        result = socket.getaddrinfo(hostname,None,0,socket.SOCK_STREAM)
        return [x[4][0] for x in result]


    def gethostname(ipaddr):
        return socket.gethostbyaddr(ipaddr)[0]




    try:

        hostname = gethostname(sys.argv[1])

        ipaddrs = getipaddrs(hostname)


    except socket.herror,e:
        print "No host names available for %s;this may be normal." % sys.argv[1]
        sys.exit(0)

    except socket.gaierror,e:
        print "Got hostname %s,but it could not be forward-resolved: %s" % (hostname,str(e))
        sys.exit(1)



    if not sys.argv[1] in ipaddrs:
        print "Got hostname %s.   but on forward lookup," % hostname
        print "original IP %s did not appear in IP address list." % sys.argv[1]
        #print "   %s" % (hostname)
        sys.exit(1)



    print "Validated hostname:%s" % (hostname)


     
     
     
     
     
     
    获得环境信息
     
     
     
    import sys,socket

    def getipaddrs(hostname):
        result = socket.getaddrinfo(hostname,None,0,socket.SOCK_STREAM)
        return [x[4][0] for x in result]




    hostname = socket.gethostname()

    print "Host name:", hostname





    print "Fully-qualified name:", socket.getfqdn(hostname)

    try:
        print "IP address:",getipaddrs(hostname)

    except socket.gaierror,e:
        print "Couldn't not get IP addresses: %s",(e)

     
     
     
     
     
    使用PyDNS进行高级查询
     
     
     
    DNS Records
     
         当您执行任何类型的查询时,不管是通过PyDNS,还是通过前面介绍的操作系统的查询功能,您都会得到来自一个域名服务器多种类型的records。下面是您会遇到的大多数records列表:
     
     
     
     
     
     
    简单的PyDNS查询
         
         PyDNS 库提供了 Python模块DNS。首先您应该在应用程序中调用DNS.DiscoverNameServers()   它可以使您找到系统中的名称服务器,在Windows系统中是注册表(registry),在UNIX系统上是 /etc/resolv.conf    全部的Pydns查询会被发送到这些服务器上。
     
     
     
     
     
    初始化名称服务器后,下一步需要建立一个请求对象,这是通过调用DNS.Request()来实现的。这个对象可以用来发出任何DNS查询请求。
     
     
     
    import sys,DNS

    query = sys,DNS


    query = sys.argv[1]

    DNS.DiscoverNameServers()


    reqobj = DNS.Request()



    answerobj = reqobj.req(name = query,qtype = DNS.Type.ANY)

    if not len(answerobj.answers):
        print "NOT FOUND."

    for item in answerobj.answers:
        print "%-5s %s" % (item['typename'],item['data'])
     
     
     
     
     
    没用啊!!!!
     
     
     
     
    查询特殊的名称服务器
         
     
     
     
  • 相关阅读:
    fullCalendar改造计划之带农历节气节假日的万年历(转)
    Linked List Cycle
    Remove Nth Node From End of List
    Binary Tree Inorder Traversal
    Unique Binary Search Trees
    Binary Tree Level Order Traversal
    Binary Tree Level Order Traversal II
    Plus One
    Remove Duplicates from Sorted List
    Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/elliottc/p/4842756.html
Copyright © 2011-2022 走看看