天天看點

java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

第五章

  1. 對于HTTP的POST請求方式,使用者送出的表單資料位于HTTP請求的哪一部分?(B)

    A 請求頭中

    B 請求正文中

    資源表示在請求主體中發送,放在首部後面。也就是說,它會按順序發送以下4項:

    (1)一個起始行,包括方法、路徑和查詢字元串,以及HTTP版本。

    (2)一個HTTP首部。

    (3)一個空行(兩個連續的回車/換行對)。

    (4)請求正文。

    例如,下面這個POST請求向伺服器發送表單資料:

    POST /cgi-bin/register.pl HTTP 1.0
    	Date: Sun, 27 Apr 2013 12:32:36
    	Host: www. cafeaulait. org
    	Content-type: application/x-WWW- form-urlencoded
    	Content -length: 54
    
    	username=Elliotte+Harold&email =elharo%4oibiblio. org
               

    在這個例子中,主體包含一個application/x www-form -urlencoded資料,但并不隻有這一種可能。一般來講,主體可以包含任意的位元組。不過,HTTP首部要包括兩個字段來指定主體的性質:

    一個Content-length字段,指定主體中有多少位元組(前面的例子中為54位元組)。

    一個Content-type字段,指定類型的MIME媒體類型(前面的例子中内容類型為application/x-www-form-urlencoded)。

    java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析
  2. HTTP請求中的請求頭與請求正文之間必須以空行隔開,同樣,HTTP響應中的響應頭與響應正文之間也必須以空行隔開。這句話是否正确?(A)

    A 正确

    B 不正确

    http響應格式

    HTTP應答與HTTP請求相似,HTTP響應也由3個部分構成,分别是:

    (1)狀态行

    (2)響應頭(Response Header)

    (3)空格

    (4)響應正文

    在接收和解釋請求消息後,伺服器會傳回一個HTTP響應消息。

    狀态行由協定版本、數字形式的狀态代碼、及相應的狀态描述,各元素之間以空格分隔。

    java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析
  3. 在HTTP響應結果中,哪個狀态代碼表示響應成功?(C)

    A 404

    B 305

    C 200

    D 500

    200~299的狀态碼表示成功

    300~399的狀态碼指資源重定向

    400~499的狀态碼指用戶端請求出錯

    500~599的狀态碼指服務端出錯

  4. ServerSocket與Socket都有一個SO_TIMEOUT選項,它們的作用是否相同?(B)

    A 相同

    B 不同

    ServerSocket中,SO_TIMEOUT:表示等待客戶連接配接的逾時時間。

    Socket中,SO_TIMEOUT:表示接收資料時的等待逾時時間。

  5. 對于以下程式代碼:
    ServerSocket serverSocket=new ServerSocket(8000);
    serverSocket.setReuseAddress(true);  
               

    哪個說法是正确的?(C)

    A 以上代碼運作時出錯

    B 以上代碼編譯時出錯

    C 以上代碼盡管編譯和運作不會出錯,但對SO_REUSEADDR選項的設定無效

    D 以上說法都不正确

    SO_REUSEADDR:表示是否允許重用伺服器所綁定的位址,應該在綁定在任何端口之前設定。此題已經在SO_REUSEADDR之前綁定了端口,是以設定無效。

    改寫:

    ServerSocket serverSocket=new ServerSocket();     
    serverSocket.setReuseAddress(true);           	 //設定ServerSocket的選項 
    serverSocket.bind(new InetSocketAddress(8000));   //與8000端口綁定
               
  6. 如何判斷一個ServerSocket已經與特定端口綁定,并且還沒有被關閉? (B)

    A boolean isOpen=serverSocket.isBound();

    B boolean isOpen=serverSocket.isBound() && !serverSocket.isClosed();

    C boolean isOpen=serverSocket.isBound() && serverSocket.isConnected();

    D boolean isOpen=!serverSocket.isClosed();

    (1)測試一個ServerSocket是否被關閉:isClosed()

    (2)測試一個ServerSocket是否綁定到過某個端口上:isBound()

    (3)測試一個ServerSocket是否打開

    public static Boolean isOpen(ServerSocket ss){
    	        return ss.isBound()&& !ss.isClosed();
    	}
               
  7. 關于ServerSocket構造方法的backlog參數,以下哪些說法是正确的?(ABCDF)

    A backlog參數用來顯式設定作業系統中的連接配接請求隊列的長度。

    B 如果沒有設定backlog參數,那麼連接配接請求隊列的長度由作業系統決定。

    C 當伺服器端的連接配接請求隊列已滿,用戶端就無法建立與伺服器的連接配接。

    D 如果backlog參數的值大于作業系統限定的隊列的最大長度,那麼backlog參數被忽略。

    E 連接配接請求隊列直接由ServerSocket建立并管理。

    F ServerSocket的accept()方法從連接配接請求隊列中取出連接配接請求。

    serverSocket = new ServerSocket(port,3); //連接配接請求隊列的長度為3

    ServerSocket構造方法的backlog參數用來顯式設定連接配接請求隊列的長度,它将覆寫作業系統限定的隊列的最大長度(一般為50)。

    在以下幾種情況,仍然會采用作業系統限定的隊列的最大長度:

    (1)backlog參數的值大于作業系統限定的隊列的最大長度。

    (2)backlog參數的值小于或等于0。

    (3)在ServerSocket構造方法中沒有設定backlog參數。

    管理客戶連接配接請求的任務是由作業系統來完成的。作業系統把這些連接配接請求存儲在一個先進先出的隊列中。許多作業系統限定了隊列的最大長度,一般為50。當隊列中的連接配接請求達到了隊列的最大容量時,伺服器程序所在的主機會拒絕新的連接配接請求。隻有當伺服器程序通過ServerSocket的accept()方法從隊列中取出連接配接請求,使隊列騰出空位時,隊列才能繼續加入新的連接配接請求。

小結:

  1. HTTP互動的基本過程

    用戶端與伺服器的80端口(或其它端口)連接配接TCP連接配接

    用戶端向伺服器發送HTTP請求(Request)

    務器向用戶端發送HTTP響應(Response)

    伺服器關閉TCP連接配接

  2. 注意:

    HTTP協定是無狀态的

    一個Request對應且隻對應一個Response

    Response是被動的

  3. 實作并發伺服器的三種方式:

    (1)為每個客戶配置設定一個工作線程。

    (2)利用JDK的Java類庫中現成的線程池,由它的工作線程來為客戶服務。

    (3)采用非阻塞的方式來實作伺服器。

  4. 為每個客戶配置設定一個線程
    java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析
  5. 使用JDK類庫提供的線程池
    java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

第六章

  1. 預設情況下,SocketChannel對象處于什麼模式?(A)

    A 阻塞模式

    B 非阻塞模式

    解析:配置非阻塞模式,

    serverChannel. configureBlocking(false);

  2. 對于以下代碼:
    int n=socketChannel.read(byteBuffer);  //假定n>=0
    byteBuffer.flip();
               

    假定執行socketChannel.read(byteBuffer)方法前,byteBuffer的容量、極限和位置分别為c、l和p,執行完以上代碼後,byteBuffer的容量、極限和位置分别是多少?(B)

    A 容量為c,極限為l,位置為p+n

    B 容量為c,極限為p+n,位置為0

    C 容量為l,極限為p+n,位置為0

    D 容量為c,極限為p+n,位置為p+n

    在Java NIO程式設計中,對緩沖區操作常常需要使用 java.nio.Buffer中的 flip()方法。

    Buffer 中的 flip() 方法涉及到 Buffer 中的capacity、position、limit三個概念。

    (1)capacity:在讀/寫模式下都是固定的,就是我們配置設定的緩沖大小(容量)。

    (2)limit:在寫模式下表示最多能寫入多少資料,此時和capacity相同。在讀模式下表示最多能讀多少資料,此時和緩存中的實際資料大小相同。

    (3)position:類似于讀/寫指針,表示目前讀(寫)到什麼位置。

    flip():Buffer有兩種模式,寫模式和讀模式。在寫模式下調用flip()之後,Buffer從寫模式變成讀模式,那麼limit就設定成了position目前的值(即目前寫了多少資料),postion會被置為0,以表示讀操作從緩存的頭開始讀。也就是說調用flip()之後,讀/寫指針position指到緩沖區頭部,并且設定了最多隻能讀出之前寫入的資料長度(而不是整個緩存的容量大小)。

    java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

    上三個屬性的關系為:容量>=極限>=位置>=0

    擴充:

    public final Buffer mark()和public final Buffer reset():用于标記位置将來回頭重讀或重寫

    public final Buffer clear():“清空”緩沖區,把極限設為容量,再把位置設為0。

    public final Buffer rewind():不改變極限,把位置設為0

    public final Buffer flip():把極限設為位置,再把位置設為0。

    public final int remaining():傳回Buffer的剩餘容量,取值等于極限-位置

    public final boolean hasRemaining():Buffer是否還有剩餘容量

    除了向Buffer裡寫資料的方法put()之外,Buffer的其它方法都不會改變Buffer中現有的值

  3. 在哪些情況,SelectionKey對象會失效?(ACD)

    A 程式調用SelectionKey的cancel()方法。

    B 程式調用SelectionKey的close()方法。

    C 關閉與SelectionKey關聯的Channel。

    D 與SelectionKey關聯的Selector被關閉。

    在SelectionKey對象的有效期間,Selector會一直監控與SelectionKey對象相關的事件,如果事件發生,就會把SelectionKey對象加入到selected-keys集合中。

    在以下情況,SelectionKey對象會失效,這意味着Selector再也不會監控與它相關的事件:

    (1)程式調用SelectionKey的cancel()方法。

    (2)關閉與SelectionKey關聯的Channel。

    (3)與SelectionKey關聯的Selector被關閉。

  4. SocketChannel可能發生哪些事件?(BCD)

    A SelectionKey.OP_ACCEPT:接收連接配接就緒事件

    B SelectionKey.OP_CONNECT:連接配接就緒事件。

    C SelectionKey.OP_READ:讀就緒事件。

    D SelectionKey.OP_WRITE:寫就緒事件。

    SelectionKey類的一些靜态常量表示事件類型

    (1)ServerSocketChannel隻可能發生一種事件:

    SelectionKey.OP_ACCEPT:接收連接配接就緒事件

    (2)SocketChannel可能發生以下三種事件:

    SelectionKey.OP_CONNECT:連接配接就緒事件

    SelectionKey.OP_READ:讀就緒事件

    SelectionKey.OP_WRITE:寫就緒事件

  5. 在伺服器程式中,線程在哪些情況可能會進入阻塞狀态?(CDE)

    A 線程執行Socket的getInputStream()方法獲得輸入流。

    B 線程執行Socket的getOutputStream()方法獲得輸出流。

    C 線程執行ServerSocket的accept()方法。

    D 線程從Socket的輸入流讀入資料。

    E 線程向Socket的輸出流寫一批資料。

    用戶端線程進入阻塞的場景

    (1)建立連接配接時

    請求與伺服器建立連接配接時,會進入阻塞狀态,直到連接配接成功。

    (2)讀資料時

    從Socket的輸入流讀入資料時,如果沒有足夠的資料,就會進入阻塞狀态,直到讀到了足夠的資料(“足夠資料”對不同的read()方法有不同含義);或到達輸入流的末尾;或者出現了異常。

    (3)寫資料時

    線程向Socket的輸出流寫一批資料時,可能會進入阻塞狀态,直到寫出了所有的資料;或者出現異常。

    (4)關閉Socket時

    當調用Socket的setSoLinger()方法設定了關閉Socket的延遲時間,那麼當線程執行Socket的close()方法時,會進入阻塞狀态,直到底層Socket發送完所有剩餘資料;或者超過了setSoLinger()方法設定的延遲時間。

    伺服器線程進入阻塞的場景

    (1)線程執行ServerSocket的accept()方法,等待客戶的連接配接,直到接收到了客戶連接配接,才從accept()方法傳回。

    (2)線程從Socket的輸入流讀入資料時, 如果輸入流沒有足夠的資料,就會進入阻塞狀态。

    (3)線程向Socket的輸出流寫一批資料時,可能會進入阻塞狀态,等到輸出了所有的資料,或者出現異常,才從輸出流的write()方法傳回或異常中斷。

  6. 線程執行Selector對象的select(long timeout)方法時進入阻塞狀态,在哪些情況,線程會從select()方法中傳回?(ABDE)

    A 至少有一個SelectionKey的相關事件已經發生。

    B 其他線程調用了Selector對象的wakeup()方法。

    C 與Selector對象關聯的一個SocketChannel對象被關閉。

    D 目前執行select()方法的線程被其他線程中斷。

    E 超出了等待時間。

    public int select(long timeout)throws IOException

    采用阻塞的工作方式,傳回相關事件已經發生的SelectionKey對象的數目,如果一個也沒有,就進入阻塞狀态,直到出現以下情況之一才傳回:

    (1)至少一個SelctionKey對象的相關事件已經發生

    (2)其它線程調用了這個Selector對象的wakeup()方法

    (3)目前執行select()方法的線程被其它線程中斷

    (4)超出了等待時間(不會抛出異常)

小結:

7. 非阻塞IO通道技術模型

java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

8. 伺服器輪詢線程

java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

3. Java支援Socket程式設計的類

java網絡程式設計5、6章習題解析第五章第六章下一節: java網絡程式設計7、8、9習題解析

下一節: java網絡程式設計7、8、9習題解析

繼續閱讀