<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    Java網絡編程從入門到精通(4):DNS緩存

    本文為原創,如需轉載,請注明作者和出處,謝謝!

    上一篇:Java網絡編程從入門到精通(3):為什么不能直接通過IP訪問網站

        在通過DNS查找域名的過程中,可能會經過多臺中間DNS服務器才能找到指定的域名,因此,在DNS服務器上查找域名是非常昂貴的操作。在Java中為了緩解這個問題,提供了DNS緩存。當InetAddress類第一次使用某個域名(如www.csdn.net)創建InetAddress對象后,JVM就會將這個域名和它從DNS上獲得的信息(如IP地址)都保存在DNS緩存中。當下一次InetAddress類再使用這個域名時,就直接從DNS緩存里獲得所需的信息,而無需再訪問DNS服務器。

    DNS緩存在默認時將永遠保留曾經訪問過的域名信息,但我們可以修改這個默認值。一般有兩種方法可以修改這個默認值:

    1. 在程序中通過java.security.Security.setProperty方法設置安全屬性networkaddress.cache.ttl的值(單位:秒)。如下面的代碼將緩存超時設為10秒:

    java.security.Security.setProperty("networkaddress.cache.ttl"10);

    2. 設置java.security文件中的networkaddress.cache.negative.ttl屬性。假設JDK的安裝目錄是C:\jdk1.6,那么java.security文件位于c:\jdk1.6\jre\lib\security目錄中。打開這個文件,找到networkaddress.cache.ttl屬性,并將這個屬性值設為相應的緩存超時(單位:秒)。

        如果將networkaddress.cache.ttl屬性值設為-1,那么DNS緩存數據將永遠不會釋放。下面的代碼演示了使用和不使用DNS緩存所產生效果:

    package mynet;

    import java.net.*;

    public class MyDNS
    {
        
    public static void main(String[] args) throws Exception
        {
            
    // args[0]: 本機名 args[1]:緩沖時間
            if (args.length < 2)
                
    return;
            java.security.Security.setProperty(
    "networkaddress.cache.ttl", args[1]);
            
    long time = System.currentTimeMillis();
            InetAddress addresses1[] 
    = InetAddress.getAllByName(args[0]);
            System.out.println(
    "addresses1:   "
                            
    + String.valueOf(System.currentTimeMillis() - time)
                            
    + "毫秒");
            
    for (InetAddress address : addresses1)
                System.out.println(address);
            System.out.print(
    "按任意鍵繼續");
            System.in.read();
            time 
    = System.currentTimeMillis();
            InetAddress addresses2[] 
    = InetAddress.getAllByName(args[0]);
            System.out.println(
    "addresses2:   "
                            
    + String.valueOf(System.currentTimeMillis() - time)
                            
    + "毫秒");
            
    for (InetAddress address : addresses2)
                System.out.println(address);
        }
    }

        在上面的代碼中設置了DNS緩存超時(通過args[1]參數),用戶可以通過命令行參數將這個值傳入MyDNS中。這個程序首先使用getAllByName建立一個InetAddress數組,然后通過System.in.read使程序暫停。當用戶等待一段時間后,可以按任意鍵繼續,并使用同一個域名(args[0])再建立一個InetAddress數組。如果用戶等待的這段時間比DNS緩存超時小,那么無論情況如何變化,addresses2addresses1數組中的元素是一樣的,并且創建addresses2數組所花費的時間一般為0毫秒(小于1毫秒后,Java無法獲得更精確的時間)。

       測試1

    執行如下命令(將DNS緩存超時設為5秒):

    java mynet.MyDNS www.126.com 5

    運行結果1(在5秒之內按任意鍵):

    addresses1:   344毫秒
    www
    .126.com/202.108.9.77
    按任意鍵繼續
    addresses2:  0毫秒
    www
    .126.com/202.108.9.77

    運行結果2(在5秒后按任意鍵):

    addresses1:   344毫秒
    www
    .126.com/202.108.9.77
    按任意鍵繼續
    addresses2:  484毫秒
    www
    .126.com/202.108.9.77

    在上面的測試中可能出現兩個運行結果。如果在出現按任意鍵繼續…”后,在5秒之內按任意鍵繼續后,就會得到運行結果1,從這個結果可以看出,addresses2所用的時間為0毫秒,也就是說,addresses2并未真正訪問DNS服務器,而是直接從內存中的DNS緩存得到的數據。當在5秒后按任意鍵繼續后,就會得到運行結果2,這時,內存中的DNS緩存中的數據已經釋放,所以addresses2還得再訪問DNS服務器,因此,addresses2的時間是484毫秒(addresses1addresses2后面的毫秒數可能在不同的環境下的值不一樣,但一般情況下,運行結果1addresses2的值為0或是一個接近0的數,如5。運行結果2addresses2的值一般會和addresses1的值很接近,或是一個遠比0大的數,如1200)。

    測試2

    執行如下命令(ComputerName為本機的計算機名,DNS緩存超時設為永不過期[-1]):

    java mynet.MyDNS ComputerName -1

    運行結果(按任意鍵繼續之前,將192.168.18.20刪除):

    addresses1:   31毫秒
    myuniverse/
    192.168.18.10
    myuniverse/
    192.168.18.20
    按任意鍵繼續
    addresses2:   0毫秒
    myuniverse/
    192.168.18.10
    myuniverse/
    192.168.18.20

         從上面的測試可以看出,將DNS緩存設為永不過期后,無論過多少時間,按任意鍵后,addresses2任然得到了兩個IP地址(192.168.18.10192.168.18.20),而且addresses2的時間是0毫秒,但在這時192.168.18.20已經被刪除。因此可以判斷,addresses2是從DNS緩存中得到的數據。如果運行如下的命令,并在5秒后按任意鍵繼續后,addresses2就會只剩下一個IP地址(192.168.18.10)。

    java mynet.MyDNS ComputerName 5

    如果域名在DNS服務器上不存在,那么客戶端在進行一段時間的嘗試后(平均為5秒),就會拋出一個UnknownHostException異常。為了讓下一次訪問這個域名時不再等待,DNS緩存將這個錯誤信息也保存了起來。也就是說,只有第一次訪問錯誤域名時才進行5稱左右的嘗試,以后再訪問這個域名時將直接拋出UnknownHostException異常,而無需再等待5秒鐘,

    訪問域名失敗的原因可能是這個域名真的不存在,也可能是因為DNS服務器或是其他的硬件或軟件的臨時故障,因此,一般不能將這個域名錯誤信息一直保留。在Java中可以通過networkaddress.cache.negative.ttl屬性設置保留這些信息的時間。這個屬性的默認值是10秒。它也可以通過java.security.Security.setProperty方法或java.security文件來設置。下面的代碼演示了networkaddress.cache.negative.ttl屬性的用法:

    package mynet;

    import java.net.*;

    public class MyDNS1
    {
        
    public static void main(String[] args) throws Exception
        {
            java.security.Security.setProperty(
    "networkaddress.cache.negative.ttl",
                            
    "5");
            
    long time = 0;
            
    try
            {
                time 
    = System.currentTimeMillis();
                InetAddress.getByName(
    "www.ppp123.com");
            }
            
    catch (Exception e)
            {
                System.out.println(
    "www.ppp123.com不存在! address1: "
                                
    + String.valueOf(System.currentTimeMillis() - time)
                                
    + "毫秒");
            }
            
    //Thread.sleep(6000); // 延遲6秒
            try
            {
                time 
    = System.currentTimeMillis();
                InetAddress.getByName(
    "www.ppp123.com");
            }
            
    catch (Exception e)
            {
                System.out.println(
    "www.ppp123.com不存在! address2: "
                                
    + String.valueOf(System.currentTimeMillis() - time)
                                
    + "毫秒");
            }
        }
    }

    在上面的代碼中networkaddress.cache.negative.ttl屬性值設為5秒。這個程序分別測試了address1address2訪問www.ppp123.com(這是個不存在的域名,讀者可以將其換成任何不存在的域名)后,用了多長時間拋出UnknownHostException異常。

    運行結果:

    www.ppp123.com不存在! address1:  4688毫秒
    www.ppp123.com不存在! address2:  0毫秒

        我們從上面的運行結果可以看出,address2使用了0毫秒就拋出了異常,因此,可以斷定address2是從DNS緩存里獲得了域名www.ppp123.com不可訪問的信息,所以就直接拋出了UnknowHostException異常。如果將上面代碼中的延遲代碼的注釋去掉,那么可能得到如下的運行結果:

    www.ppp123.com不存在! address1:  4688毫秒
    www.ppp123.com不存在! address1:  4420毫秒

    從上面的運行結果可以看出,在第6秒時,DNS緩存中的數據已經被釋放,因此,address2仍需要訪問DNS服務器才能知道www.ppp123.com是不可訪問的域名。

    在使用DNS緩存時有兩點需要注意:

    1. 可以根據實際情況來設置networkaddress.cache.ttl屬性的值。一般將這個屬性的值設為-1。但如果訪問的是動態映射的域名(如使用動態域名服務將域名映射成ADSL的動態IP, 就可能產生IP地址變化后,客戶端得到的還是原來的IP地址的情況。

    2. 在設置networkaddress.cache.negative.ttl屬性值時最好不要將它設為-1否則如果一個域名因為暫時的故障而無法訪問,那么程序再次訪問這個域名時,即使這個域名恢復正常,程序也無法再訪問這個域名了。除非重新運行程序。

    下一篇:Java網絡編程從入門到精通(5):使用InetAddress類的getHostName方法獲得域名





    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2009-04-06 21:06 銀河使者 閱讀(4870) 評論(2)  編輯  收藏 所屬分類: java 原創網絡編程

    評論

    # re: Java網絡編程從入門到精通(4):DNS緩存  回復  更多評論   

    老師,你好。現在jdk1.7.0_06中,在security文件夾下,沒有找到networkaddress.cache.negative.ttl屬性,是因為位置變了么?
    2014-06-13 10:58 | krave

    # re: Java網絡編程從入門到精通(4):DNS緩存  回復  更多評論   

    找到了 找到了
    就是java.security這個文件,打開以后就能設置了。
    2014-06-13 11:30 | krave
    主站蜘蛛池模板: 亚洲?V乱码久久精品蜜桃| 亚洲人成未满十八禁网站| 黄色免费网址大全| 亚洲一区二区三区在线观看精品中文| a国产成人免费视频| 91亚洲国产成人久久精品网址| 九九精品成人免费国产片| 国产亚洲欧洲Aⅴ综合一区| 久久亚洲免费视频| 免费网站看v片在线香蕉| 成人久久久观看免费毛片| 又大又硬又爽免费视频| 你懂的免费在线观看| 在线亚洲午夜片AV大片| 国产精品入口麻豆免费观看| 美女无遮挡免费视频网站| 亚洲卡一卡2卡三卡4卡无卡三| 可以免费观看的国产视频| 亚洲精品午夜国产va久久| 亚洲精品无码鲁网中文电影| 国产精品美女午夜爽爽爽免费| 亚洲啪AV永久无码精品放毛片| 中文字幕亚洲日韩无线码| 成人网站免费观看| 久久免费美女视频| 一级毛片aa高清免费观看| 亚洲无吗在线视频| 免费在线观看黄色毛片| 91短视频免费在线观看| 亚洲熟妇少妇任你躁在线观看| 亚洲成a人片在线观看日本| 国产乱子影视频上线免费观看| 2019中文字幕在线电影免费| 无遮挡国产高潮视频免费观看| 亚洲一区二区三区高清不卡 | 国产片免费在线观看| AV大片在线无码永久免费| 最近免费中文字幕MV在线视频3| 爱情岛论坛亚洲品质自拍视频网站| 亚洲精品国产日韩无码AV永久免费网| 国产成人免费ā片在线观看老同学|