文加圖, 理解Http請(qǐng)求與響應(yīng)
標(biāo)簽 : 網(wǎng)絡(luò)
作者 : 王乾
時(shí)間 : 2016.08.01
blog : http://blog.csdn.net/oncealong
1. http請(qǐng)求和響應(yīng)步驟
在講解OkHttp之前, 我們首先來個(gè)高清大圖, 看下http請(qǐng)求的整個(gè)步驟, 有個(gè)整體概念.
2. http每一步詳細(xì)內(nèi)容
在一次完整的HTTP通信過程中, Web瀏覽器與Web服務(wù)器之間將完成下列7個(gè)步驟:
2.1 建立TCP連接
在HTTP工作開始之前, Web瀏覽器首先要通過網(wǎng)絡(luò)與Web服務(wù)器建立連接, 該連接是通過TCP來完成的, 該協(xié)議與IP協(xié)議共同構(gòu)建Internet, 即著名的TCP/IP協(xié)議族, 因此Internet又被稱作是TCP/IP網(wǎng)絡(luò).
HTTP是比TCP更高層次的應(yīng)用層協(xié)議, 根據(jù)規(guī)則, 只有低層協(xié)議建立之后才能進(jìn)行更高層協(xié)議的連接, 因此, 首先要建立TCP連接, 一般TCP連接的端口號(hào)是80.
TCP連接中我們比較熟悉的就是三次握手, 但是為什么是三次而不是兩次或四次呢? 這里我想到了一個(gè)比喻來讓大家明白.
敵人封鎖江面, 我方間諜和聯(lián)絡(luò)員只能通過電報(bào)機(jī)隔著江面交流. 但是那時(shí)的電報(bào)機(jī)質(zhì)量不穩(wěn)定, 有可能會(huì)出現(xiàn)失靈的情況. 所以就出現(xiàn)了如下對(duì)話:
間諜: 聯(lián)絡(luò)員, 你能收到我發(fā)的話么? 你要是能收到, 就說明我這個(gè)電報(bào)機(jī)可以發(fā)電報(bào).
聯(lián)絡(luò)員: 間諜, 我收到你發(fā)的話了, 這說明我的電報(bào)機(jī)可以收. 但是我不確定我的電報(bào)機(jī)能不能發(fā), 你能收到我發(fā)的這句話么? 你要是能收到, 就說明我的電報(bào)機(jī)是可以發(fā)電報(bào)的.
間諜: 聯(lián)絡(luò)員, 我收到你的話了. 我的電報(bào)機(jī)也是能發(fā)能收, 我們可以正式交流情報(bào)了.
這個(gè)故事代表了tcp的三次握手, 確定了client和server的發(fā)送和接收功能都正常. 如果只發(fā)送兩次, 那么不能確定client和server都能正常收發(fā); 如果發(fā)送四次或者更多, 理論上當(dāng)然也是可以的, 但是網(wǎng)絡(luò)環(huán)境十分復(fù)雜, 任何兩次請(qǐng)求間都可能出現(xiàn)錯(cuò)誤, 多出的請(qǐng)求次數(shù)并無法確保下一個(gè)請(qǐng)求一定安全.
希望通過這個(gè)故事讓大家明白為什么會(huì)有tcp三次握手.
2.2 Web瀏覽器向Web服務(wù)器發(fā)送請(qǐng)求命令
一旦建立了TCP連接, Web瀏覽器就會(huì)向Web服務(wù)器發(fā)送請(qǐng)求命令
例如:GET/sample/hello.jsp HTTP/1.1
2.3 Web瀏覽器發(fā)送請(qǐng)求頭信息
瀏覽器發(fā)送其請(qǐng)求命令之后, 還要以頭信息的形式向Web服務(wù)器發(fā)送一些別的信息, 這些信息用來描述瀏覽器自己. 之后瀏覽器發(fā)送了一空白行來通知服務(wù)器, 表示它已經(jīng)結(jié)束了該頭信息的發(fā)送. 若是post請(qǐng)求, 還會(huì)在發(fā)送完請(qǐng)求頭信息之后發(fā)送請(qǐng)求體.
2.4 Web服務(wù)器應(yīng)答
客戶機(jī)向服務(wù)器發(fā)出請(qǐng)求后, 服務(wù)器會(huì)向客戶機(jī)回送應(yīng)答.
HTTP/1.1 200 OK
應(yīng)答的第一部分是協(xié)議的版本號(hào)和應(yīng)答狀態(tài)碼
2.5 Web服務(wù)器發(fā)送應(yīng)答頭信息
正如客戶端會(huì)隨同請(qǐng)求發(fā)送關(guān)于自身的信息一樣,服務(wù)器也會(huì)隨同應(yīng)答向用戶發(fā)送關(guān)于它自己的數(shù)據(jù)及被請(qǐng)求的文檔. 最后以一個(gè)空白行來表示頭信息發(fā)送到此結(jié)束.
2.6 Web服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù)
Web服務(wù)器向?yàn)g覽器發(fā)送頭信息后, 它就以Content-Type
應(yīng)答頭信息所描述的格式發(fā)送用戶所請(qǐng)求的實(shí)際數(shù)據(jù)
2.7 Web服務(wù)器關(guān)閉TCP連接
一般情況下, 一旦Web服務(wù)器向?yàn)g覽器發(fā)送了請(qǐng)求數(shù)據(jù), 它就要關(guān)閉TCP連接. 如果瀏覽器或者服務(wù)器在其頭信息加入了這行代碼
Connection:keep-alive
TCP連接在發(fā)送后將仍然保持打開狀態(tài). 于是, 瀏覽器可以繼續(xù)通過相同的連接發(fā)送請(qǐng)求. 保持連接節(jié)省了為每個(gè)請(qǐng)求建立新連接所需的時(shí)間, 還節(jié)約了網(wǎng)絡(luò)帶寬.
3. 使用fiddler抓包驗(yàn)證請(qǐng)求信息和響應(yīng)信息
這里, 給大家推薦一個(gè)抓包工具fiddler
, 免費(fèi)好用. 而且可以在本機(jī)設(shè)置代理, 直接抓取同局域網(wǎng)的android或ios手機(jī)的數(shù)據(jù)包, 如果需要請(qǐng)谷歌fiddler android
.
這里我們安裝fiddler
后, 打開composer
, composer
可以直接構(gòu)建http請(qǐng)求并執(zhí)行.
3.1 get的請(qǐng)求和應(yīng)答
我們首先構(gòu)建一個(gè)get
請(qǐng)求, 設(shè)置如下:
可以看到, 我們需要設(shè)置請(qǐng)求方法
, 請(qǐng)求地址
, 請(qǐng)求協(xié)議
和請(qǐng)求頭
.
點(diǎn)擊execute
, 即可執(zhí)行我們的請(qǐng)求. 上圖左欄即是我們請(qǐng)求的結(jié)果, 點(diǎn)擊查看. 下圖就是我們http請(qǐng)求的raw數(shù)據(jù), raw
代表沒有為了方便觀看而格式化的數(shù)據(jù).
接下來看下我們請(qǐng)求的應(yīng)答:
3.2 post的請(qǐng)求和應(yīng)答
post請(qǐng)求, 因?yàn)樯婕暗叫枰蟼鞯恼?qǐng)求體, 手頭沒有現(xiàn)成的服務(wù)器, 所以我們用ithome
的登陸來舉例說明. 下圖是登陸時(shí)post的具體數(shù)據(jù):
我們分析下, 其請(qǐng)求方法為post
, 請(qǐng)求地址為btnLogin_Click
, 請(qǐng)求協(xié)議為HTTP/1.1
. 然后是請(qǐng)求頭, 請(qǐng)求頭中有一個(gè)比較重要的設(shè)置是Content-Type: application/json; charset=utf-8
. 表示我們會(huì)上傳一個(gè)json文件, json文件的格式是utf-8, 這里面保存的就是用戶名和密碼, 通過post請(qǐng)求在請(qǐng)求體中傳輸給服務(wù)器.
json文件具體內(nèi)容是:
這正驗(yàn)證了我們上文所說.
我們看下post請(qǐng)求的響應(yīng):
我們又看到了Content-Type: application/json; charset=gb2312
, 這說明在響應(yīng)頭結(jié)束后, 會(huì)有一個(gè)gb2312編碼的json. 我們看下這個(gè)json的內(nèi)容:
看到我們的請(qǐng)求返回的內(nèi)容就是ok
, 代表有這個(gè)用戶名和密碼正確.
4. 結(jié)語
希望通過這一節(jié), 讓大家對(duì)http協(xié)議有個(gè)整體上的認(rèn)識(shí), 清楚get和post請(qǐng)求和響應(yīng)的組成.
如果我們要寫一個(gè)庫來完成http協(xié)議的功能, 那么我們應(yīng)該需要控制 請(qǐng)求方法: get/post
, 請(qǐng)求地址: url
, 請(qǐng)求協(xié)議: http/1.1
, 請(qǐng)求頭: 描述自身信息
, 請(qǐng)求體: post時(shí)才有
, 有了這些我們才能構(gòu)建一個(gè)http請(qǐng)求. 當(dāng)響應(yīng)時(shí), 我們應(yīng)該需要一些字段代表 應(yīng)答協(xié)議: http/1.1
, 響應(yīng)碼: 200
, 應(yīng)答頭: content-type等描述自身信息
, 響應(yīng)體: 如json, html等
, 這樣我們才能完全的表示我們的返回響應(yīng).
有了這些概念, 下一節(jié), 我們講解OkHttp將會(huì)特別輕松愉快. 因?yàn)镺kHttp完成的就是get或post請(qǐng)求, 所以O(shè)kHttp中就有類來代表我們剛才講到的 請(qǐng)求方法
, 請(qǐng)求地址
, 請(qǐng)求協(xié)議
等概念, 了解了OkHttp中的這些類, 那么OkHttp你也就學(xué)會(huì)怎么使用了.
謝謝下列文章:
http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/2123548.html