Android網絡編程1Http協議原理

前言

這篇文章是這個系列的開篇,做爲移動開發者,開發的應用難免會對網絡進行訪問,雖然如今已經有不少的開源庫幫助咱們能夠垂手可得的訪問網絡,可是咱們仍要去了解網絡訪問的原理,這也是一個優秀開發人員所必備的知識點。這篇文章咱們就先來了解一下HTTP協議原理。html

1.HTTP簡介

HTTP是一個屬於應用層的面向對象的協議,因爲其簡捷、快速的方式,適用於分佈式超媒體信息系統。它於1990年提出,通過幾年的使用與發展,獲得不斷地完善和擴展。android

HTTP協議的主要特色

  1. 支持C/S(客戶/服務器)模式。
  2. 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST,每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
  3. 靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  4. 無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
  5. 無狀態:HTTP協議是無狀態協議,無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。

HTTP URL 的格式以下

http://host[":"port][abs_path]

http表示要經過HTTP協議來定位網絡資源;host表示合法的Internet主機域名或者IP地址;port指定一個端口號,爲空則使用默認端口80;abs_path指定請求資源的URI(Web上任意的可用資源)。
HTTP有兩種報文分別是請求報文和響應報文,讓咱們先來看看請求報文。nginx

2.HTTP的請求報文

先來看看請求報文的通常格式:
web

一般來講一個HTTP請求報文由請求行、請求報頭、空行、和請求數據4個部分組成。api

請求行

請求行由請求方法,URL字段和HTTP協議的版本組成,格式以下:瀏覽器

Method Request-URI HTTP-Version CRLF

其中 Method表示請求方法;Request-URI是一個統一資源標識符;HTTP-Version表示請求的HTTP協議版本;CRLF表示回車和換行(除了做爲結尾的CRLF外,不容許出現單獨的CR或LF字符)。緩存

HTTP請求方法有8種,分別是GET、POST、DELETE、PUT、HEAD、TRACE、CONNECT 、OPTIONS。其中PUT、DELETE、POST、GET分別對應着增刪改查,對於移動開發最經常使用的就是POST和GET了。服務器

  1. GET:請求獲取Request-URI所標識的資源
  2. POST:在Request-URI所標識的資源後附加新的數據
  3. HEAD 請求獲取由Request-URI所標識的資源的響應消息報頭
  4. PUT 請求服務器存儲一個資源,並用Request-URI做爲其標識
  5. DELETE 請求服務器刪除Request-URI所標識的資源
  6. TRACE 請求服務器回送收到的請求信息,主要用於測試或診斷
  7. CONNECT 保留未來使用
  8. OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

例如我去訪問個人CSDN博客地址請求行是:網絡

GET http://blog.csdn.net/itachi85 HTTP/1.1

請求報頭

在請求行以後會有0個或者多個請求報頭,每一個請求報頭都包含一個名字和一個值,它們之間用「:」分割。請求頭部會以一個空行,發送回車符和換行符,通知服務器如下不會有請求頭。關於請求報頭,會在後面的消息報頭一節作統一的解釋。session

請求數據

請求數據不在GET方法中使用,而是在POST方法中使用。POST方法適用於須要客戶填寫表單的場合,與請求數據相關的最經常使用的請求頭是Content-Type和Content-Length。

3.HTTP的響應報文

先來看看響應報文的通常格式:

HTTP的響應報文由狀態行、消息報頭、空行、響應正文組成。響應報頭後面會講到,響應正文是服務器返回的資源的內容,先來看看狀態行。

狀態行

一、狀態行格式以下:

HTTP-Version Status-Code Reason-Phrase CRLF

其中,HTTP-Version表示服務器HTTP協議的版本;Status-Code表示服務器發回的響應狀態代碼;Reason-Phrase表示狀態代碼的文本描述。
狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:

  • 100~199:指示信息,表示請求已接收,繼續處理
  • 200~299:請求成功,表示請求已被成功接收、理解、接受
  • 300~399:重定向,要完成請求必須進行更進一步的操做
  • 400~499:客戶端錯誤,請求有語法錯誤或請求沒法實現
  • 500~599:服務器端錯誤,服務器未能實現合法的請求

常見的狀態碼以下:

  • 200 OK:客戶端請求成功
  • 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解
  • 401 Unauthorized:請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
  • 403 Forbidden:服務器收到請求,可是拒絕提供服務
  • 500 Internal Server Error:服務器發生不可預期的錯誤
  • 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

例如訪問個人CSDN博客地址響應的狀態行是:

HTTP/1.1 200 OK

4.HTTP的消息報頭

消息報頭分爲通用報頭、請求報頭、響應報頭、實體報頭等。消息頭由鍵值對組成,每行一對,關鍵字和值用英文冒號「:"分隔。

通用報頭

既能夠出如今請求報頭,也能夠出如今響應報頭中

  • Date:表示消息產生的日期和時間
  • Connection:容許發送指定鏈接的選項,例如指定鏈接是連續的,或者指定「close」選項,通知服務器,在響應完成後,關閉鏈接
  • Cache-Control:用於指定緩存指令,緩存指令是單向的(響應中出現的緩存指令在請求中未必會出現),且是獨立的(一個消息的緩存指令不會影響另外一個消息處理的緩存機制)

請求報頭

請求報頭通知服務器關於客戶端求求的信息,典型的請求頭有:

  • Host:請求的主機名,容許多個域名同處一個IP地址,即虛擬主機
  • User-Agent:發送請求的瀏覽器類型、操做系統等信息
  • Accept:客戶端可識別的內容類型列表,用於指定客戶端接收那些類型的信息
  • Accept-Encoding:客戶端可識別的數據編碼
  • Accept-Language:表示瀏覽器所支持的語言類型
  • Connection:容許客戶端和服務器指定與請求/響應鏈接有關的選項,例如這是爲Keep-Alive則表示保持鏈接。
  • Transfer-Encoding:告知接收端爲了保證報文的可靠傳輸,對報文采用了什麼編碼方式。

響應報頭

用於服務器傳遞自身信息的響應,常見的響應報頭:

  • Location:用於重定向接受者到一個新的位置,經常使用在更換域名的時候
  • Server:包含可服務器用來處理請求的系統信息,與User-Agent請求報頭是相對應的

實體報頭

實體報頭用來定於被傳送資源的信息,既能夠用於請求也可用於響應。請求和響應消息均可以傳送一個實體,常見的實體報頭爲:

  • Content-Type:發送給接收者的實體正文的媒體類型
  • Content-Lenght:實體正文的長度
  • Content-Language:描述資源所用的天然語言,沒有設置則該選項則認爲實體內容將提供給全部的語言閱讀
  • Content-Encoding:實體報頭被用做媒體類型的修飾符,它的值指示了已經被應用到實體正文的附加內容的編碼,於是要得到Content-Type報頭域中所引用的媒體類型,必須採用相應的解碼機制。
  • Last-Modified:實體報頭用於指示資源的最後修改日期和時間
  • Expires:實體報頭給出響應過時的日期和時間

5.應用舉例

要想查看網頁或者手機請求網絡的請求報文和響應報文有不少種方法,這裏推薦採用Fiddler,在Android利用Fiddler進行網絡數據抓包這篇文章中詳盡介紹瞭如何使用Fiddler,在這裏就不贅述了。
打開Fiddler,而後用瀏覽器訪問個人CSDN博客網站:

點擊紅色畫筆的區域就能夠看到請求報文和響應報文了

請求報文:

GET http://blog.csdn.net/itachi85 HTTP/1.1                                //請求行
Host: blog.csdn.net                                                       //請求報頭
Connection: keep-alive
Cache-Control: max-age=0       
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 QQBrowser/9.3.6872.400
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: bdshare_firstime=1443768140949; uuid_tt_dd=5028529250430960147_20151002;
...省略

很容易看出訪問的是個人博客地址http://blog.csdn.net/itachi85,請求的方法是GET,由於是GET方法因此並無請求數據。

響應報文:

HTTP/1.1 200 OK                                                         //狀態行
Server: openresty                                                       //響應報頭
Date: Sun, 27 Mar 2016 08:26:54 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept-Encoding
Cache-Control: private
X-Powered-By: PHP 5.4.28
Content-Encoding: gzip
                                                                        //不能省略的空格
28b5                                    
        }ysI   1ߡFsgl n- ]{^_ { 'z!     C ,  m# 0 !l   `  4x  ly .ݪ*  
  ڴzAt_Xl *  9'O  ɬ  '  ק   3  ^1a
...省略

響應報文沒什麼可說的,接下來咱們配置好手機網絡代理,訪問一個應用的界面

請求報文:

POST http://patientapi.shoujikanbing.com/api/common/getVersion HTTP/1.1       //請求行
Content-Length: 226                                                          //請求報頭
Content-Type: application/x-www-form-urlencoded
Host: patientapi.shoujikanbing.com
Connection: Keep-Alive
User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; MI NOTE LTE Build/KTU84P) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
Accept-Encoding: gzip
                                                             //不能省略的空格,下面是請求數據
clientversion=2_2.0.0&time=1459069342&appId=android&channel=hjwang&sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9&token=b191944d680145b5ed97f2f4ccf03058&deviceId=869436020220717&type=2&version=2.0.0

從請求報文的請求行來看,請求的方法是POST,請求地址爲http://patientapi.shoujikanbing.com/api/common/getVersion,很顯然是獲取版本信息的接口。

響應報文:

HTTP/1.1 200 OK                                                              //狀態行
Server: nginx                                                               //響應報頭
Date: Sun, 27 Mar 2016 09:02:20 GMT
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; expires=Mon, 28-Mar-2016 09:02:20 GMT; Max-Age=86400; path=/; domain=.shoujikanbing.com
Set-Cookie: PHPSESSID=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; path=/; domain=.shoujikanbing.com
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
                                                   //不能省略的空格
17f                                                //實體報文編碼格式爲gzip因此顯示在這裏的響應數據是亂碼
       mP N @     "E ?    n m   1  
w ( HL (1^ P nK  E ѷ93'3gNLH  7P  $c \  T 4a6   L:+ 1dY%$g   h H   +

...省略

響應報文的實體採用的編碼格式爲爲gzip,因此在Fiddler軟件中顯示的是亂碼。

相關文章
相關標籤/搜索