<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網絡編程從入門到精通(16):客戶端套接字(Socket)的超時

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

    上一篇:Java網絡編程從入門到精通(15):為什么要使用SocketAddress來管理網絡地址

        客戶端套接字的超時(timeout)就是指在客戶端通過Socket和服務器進行通訊的過程中,由于網絡延遲,網絡阻塞等原因,造成服務器并未及時響應客戶端的一種現象。在一段時間后,客戶端由于未收到服務端的響應而拋出一個超時錯誤; 其中客戶端所等待的時間就是超時時間。

    由于生產超時錯誤的一端都是被動端;也就是說,這一端是在接收數據,而不是發送數據。對于客戶端Socket來說,只有兩個地方是在接收數據;一個是在連接服務器時;另一個是在連接服務器成功后,接收服務器發過來的數據時。因此,客戶端超時也分為兩種類型:連接超時和讀取數據超時。

    一、連接超時

    這種超時在前面的例子中已經使用過。在Socket類中只有通過connect方法的第二個參數才能指定連接超時的時間。由于使用connect方法連接服務器必須要指定IP和端口;因此,無效的IP或端口將會引發連接超時錯誤。

    二、讀取數據超時

    在連接服務器成功后,Socket所做的最重要的兩件事就是接收數據發送數據;而在接收數據時可能因為網絡延遲、網絡阻塞等原因,客戶端一直處于等待狀態;而客戶端在等待一段時間后,如果服務器還沒有發送數據到客戶端,那么客戶端Socket將會拋出一個超時錯誤。

    我們可以通過Socket類的setSoTimeout方法來設置讀取數據超時的時間;時間的單位是毫秒。這個方法必須在讀取數據之前調用才會生效。如果將超時時間設為0,則不使用超時時間;也就是說,客戶端什么時候和服務器斷開,將完全取決于服務端程序的超時設置。如下面的語句將讀取數據超時時間設為5秒。

    Socket socket = new Socket();
    socket.setSoTimeout(
    5000);
    socket.connect(… …);
    socket.getInputStream().read();

    要注意的是不要將設置連接超時和讀取數據超時設置得太小,如果值太小,如100,可能會造成服務器的數據還沒來得及發過來,客戶端就拋出超時錯誤的現象。下面的代碼給出了一個用于測試連接超時和讀取數據超時的例子。

    package mynet;

    import java.net.*;

    public class SocketTimeout
    {
        
    public static void main(String[] args)
        {
            
    long time1 = 0, time2 = 0;
            Socket socket 
    = new Socket();
            
    try
            {
                
    if (args.length < 4)
                {
                    System.out.println(
    "參數錯誤!");
                    
    return;
                }

                time1 
    = System.currentTimeMillis();
                socket.connect(
    new InetSocketAddress(args[0], Integer
                        .parseInt(args[
    1])), Integer.parseInt(args[2]));
                socket.setSoTimeout(Integer.parseInt(args[
    3]));
                time1 
    = System.currentTimeMillis();
                socket.getInputStream().read();
            }
            
    catch (SocketTimeoutException e)
            {
                
    if (!socket.isClosed() && socket.isConnected())
                    System.out.println(
    "讀取數據超時!");
                
    else
                    System.out.println(
    "連接超時");
            }
            
    catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
            
    finally
            {
                time2 
    = System.currentTimeMillis();
                System.out.println(time2 
    - time1);
            }
        }
    }

    SocketTimeout類的main方法需要4個參數:IP(域名)、端口、連接超時、讀取數據超時。下面讓我們來用一組數據來測試這個例子。

    測試1 :無效IP引發的超時錯誤

    執行如下命令:

    java mynet.SocketTimeout 192.168.18.24 80 3000 5000

    運行結果:

    連接超時
    3045

    注意:192.168.18.24是一個無效的IP;如果這個IP在網絡環境中存在,請換其它的無效的IP。在這個測試用例中不能將無效的IP換成無效的域名;這是因為如果使用了域名來連接服務器,Java會先通過DNS將域名映射成相應的IP;如果這個域名是無效的,在映射的過程中就會出錯;因此,程序也就不會執行連接服務器操作,自然也就不會拋出“連接超時”錯誤了。

    測試2 :無效端口引發的超時錯誤

    執行如下命令:

    java mynet.SocketTimeout  www.ptpress.com.cn 8888 3000 5000

    運行結果:

    連接超時
    3075

    測試3 :讀取數據超時錯誤

    執行如下命令:

    java mynet.SocketTimeout www.ptpress.com.cn 80 3000 5000

    運行結果:

    讀取數據超時!
    5008

    測試4 :將讀取數據超時設為0的效果

    執行如下命令:

    java mynet.SocketTimeout www.ptpress.com.cn 80 3000 0

    運行結果:

    Connection reset
    131519

    從前3個測試的輸出結果不難看出,每個測試用例都將連接超時和讀取數據超時分別設為30005000毫秒;而它們的運行結果并不是30005000毫秒,而是在所設定的超時時間的左右搖擺;這主要是因為系統所輸出的時間并不都是超時時間;如有一些時間是Java處理錯誤、向控制臺輸出信息的時間。另外,由于系統計時的誤差,也會影響到超時時間的準確性。但不管怎樣,超時時間總會在所設定的時間周圍搖擺。

    對于測試4,將讀取數據超時設為0后,SocketTimeout類經過了2分多鐘(131519毫秒)才拋出Connection reset錯誤。這個拋出錯誤的時間和服務端程序的超時設置有關;也就是這個錯誤是由于服務端程序主動將客戶端網絡連接斷開而產生的。

    下一篇:
    Java網絡編程從入門到精通(17):Socket類的getter和setter方法(1)





    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-05-26 08:48 銀河使者 閱讀(3908) 評論(0)  編輯  收藏 所屬分類: java 原創網絡編程

    主站蜘蛛池模板: 免费精品国产自产拍在线观看 | 久久久久成人片免费观看蜜芽| 污污视频免费观看网站| 中文字幕免费观看| 国产成人精品免费视频网页大全| 一二三四免费观看在线视频中文版 | 久久精品免费一区二区| 久久精品国产亚洲| 亚洲18在线天美| WWW国产亚洲精品久久麻豆| 精品一区二区三区免费观看| 一区二区三区观看免费中文视频在线播放 | 亚洲午夜久久久久久久久久| 亚洲国产精品自在线一区二区| 亚洲avav天堂av在线网爱情| 亚洲黄色免费网站| mm1313亚洲精品无码又大又粗| 亚洲无人区午夜福利码高清完整版| 国产成人综合久久精品亚洲| 日本高清在线免费| 亚洲春色另类小说| 叮咚影视在线观看免费完整版| 最近免费中文字幕大全| 亚洲熟女少妇一区二区| 99久久婷婷免费国产综合精品| 女人张腿给男人桶视频免费版| 久久国产成人亚洲精品影院| 33333在线亚洲| 日本免费一区二区久久人人澡| 一级毛片直播亚洲| 国产精品无码永久免费888| 在线A级毛片无码免费真人| 亚洲国产无线乱码在线观看| 69影院毛片免费观看视频在线| 91精品国产亚洲爽啪在线影院| 七次郎成人免费线路视频| 好吊妞998视频免费观看在线| 亚洲av永久中文无码精品| 亚洲国产成人精品91久久久| 亚洲综合色婷婷在线观看| 中文字幕在线观看免费视频|