上一篇描述了如何在Windows環境中快速送出封包,接下來是Linux環境了。

下列步驟適用Linux base系統:

Linux的預設安裝似乎也是沒有telnet程式,所以也必須先安裝,因為每個Linux base的安裝方式都不相同,所以可到網路查詢一下怎麼安裝telnet。下圖是CentOS的系統安裝範例:

  1. 輸入指令 yum install telnet (注意,yum必須在root帳號下執行)

  1. 安裝後的執行與Windows相同。執行telnet 192.168.21.35 8080後,貼上封包,就可以取得HTTP的Reponse了。

解析HTTP Response(回應)封包資料

在上一章我們針對HTTP的Request封包解釋過,接下來讓我們來看看HTTP的Response吧。

HTTP封包範例1

  1. HTTP/1.1 302 Found

  2. Server: Apache-Coyote/1.1

  3. Location: http://192.168.21.35:8080/xxxx/

  4. Transfer-Encoding: chunked

  5. Date: Wed, 18 May 2016 03:21:21 GMT

  6.  
  7. 0

在上一章有提過,基本上要解讀HTTP的封包,要先將封包切成三個部份:

  1. 第一行的宣告。

  2. 中間的header,以本例來說就是2~5行。

  3. 最後的資料。

這個部份在解讀Response的資料仍是相同的。

第一行的宣告 HTTP/1.1 302 Found ,要切開成二段來閱讀,一個是HTTP/1.1 是固定的,意思是這個封包導守HTTP 1.1的協定;第二個是302 Found,這個被稱為狀態碼,會依據伺服器的情況來回傳,而文字主要是給人閱讀的,程式主要判斷的部份是數字,每一個數字都有不同的意義,下方列出幾個最常遇到的狀態碼:

  1. 200 OK - 代表伺服器正常處理傳入的Request。

  2. 302 Found - 伺服器希望使用者連線到另一個網址,網址會帶在header裡的Location值裡面(參考封包的第三行)。

  3. 401 Unauthorized - 使用者未經認證,通常透過登入可以解決這個問題。

  4. 403 Forbidden - 使用者的權限不足,無法瀏灠指定的網頁。

  5. 404 Not Found - 使用者指定的網址,並無對應的網頁或資源。

  6. 500 Internal Server Error - 伺服器在執行對應的網址時出錯。

從第2行到第5行,就是我們熟悉的header,我們來大概瞭解一下它們的意思。

第二行的Server: Apache-Coyote/1.1,宣告的是處理這個HTTP的伺服器種類,將它的值Apache-Coyote/1.1貼到網路上做查詢,可以發現這個伺服器是用tomcat架設起來的。

第三行的Location: http://192.168.21.35:8080/xxxx/,通常這個Location header是配合302 Found的狀態碼才會有,目的是告知灠瀏器要轉連到那一個網址。

第四行的Transfer-Encoding: chunked,這個封包是以分段的方式來傳送的。通常HTTP封包會包含一個"Content-Length"的header,來告知這個封包有多大。因為HTTP是屬於TCP應用中的其中一種,所以會等候接收端的回應,如果接收端沒有回應的話,會再重新傳送一次,以防資料遺失。試想,一個封包如果帶了1MB的資料,結果全部傳送完後,接收端沒有回應,最後這個1MB的資料還要重新傳送,這是一件很搞笑的事,所以通常都會使用chunked(分段)的方式,告知每一段封包的長度,而在整份文件的最後會傳送一個0(第七行),表示整個Response傳送完畢。

第五行的Date: Wed, 18 May 2016 03:21:21 GMT,代表現在伺服器的時間。

第六行的空格是一個分隔,代表從下方開始,是Response的主體。

第七行開始開Response的主體;因為這個封包主要是要求使用者到另一個網址,所以沒有什麼內容,只回傳一個0,代表封包的結束。

 

HTTP封包範例2

  1. HTTP/1.1 200 OK

  2. Server: Apache-Coyote/1.1

  3. Content-Type: text/html;charset=UTF-8

  4. Content-Language: zh-TW

  5. Transfer-Encoding: chunked

  6. Date: Wed, 18 May 2016 06:43:18 GMT

  7.  
  8. 2000

  9. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">.......

封包的解讀方式都一樣,所以我們直接來解讀,這一封包有幾個重點:

  1. 狀態碼是200,代表成功取得資料。

  2. 第3行宣告資料的內容樣式(MINE TYPE),是text/html,而且需用UTF-8來解讀。

  3. 第8行的2000,代表這個封包的資料為2000位元組。

  4. 第9行則是實際的資料內容。

 

結論

其實這篇應用與上一篇是連貫的,擷取傳送到伺服器的封包後,再重覆利用傳送該封包來進行Debug,在某些狀況下非常有用的,不但可以免除一直麻煩別人進行測試,而且可以透過多次的Debug,來確保程式的正確性;甚至透過直接修改封包,來達到快速檢測的功能;以筆者曾經遇到的問題為例:

手機端的一支小程式,在下載的行為上,只能重頭下載到尾,不能支援續傳功能。

擷取封包後發現封包帶了二個相同的header,當下覺得很奇怪,就馬上

  1. 將封包文字複製到筆記本。

  2. 修改成正常的封包後。

  3. 透過telnet再重送一次,

結果發現回傳的內容就變正常了;從發現奇怪的狀況,到證明bug的原因,不會超過一分鐘。

以這種狀況為例,如果我們是從程式端去追查問題,可能花了不止四、五倍的時間還不一定能追查的到原因,而當我們從封包追回問題時,卻一下子就可以找出問題,所以建議讀者,當從一個面向追不到問題時,有時換個想法、作法,可能會有意向不到的效果。

arrow
arrow

    JAVA Programmer 發表在 痞客邦 留言(0) 人氣()