HTTP介紹

TTP屬于老話題了,在項(xiàng)目中我們經(jīng)常需要往服務(wù)端發(fā)POST或者GET請(qǐng)求掘宪,但是對(duì)于HTTP的了解不應(yīng)只局限于此蛾扇。千里之行,始于足下魏滚。越想走的遠(yuǎn)镀首,基本原理就應(yīng)該了解的透徹全面一些,僅僅停留在使用ASIHttpRequest或者AFNetWorking傳個(gè)參數(shù)發(fā)個(gè)請(qǐng)求的程度上是不夠的鼠次。這篇文章就是帶你全方面回顧一下HTTP更哄。
通過本文你能收獲哪些內(nèi)容:

·完整HTTP請(qǐng)求與響應(yīng)包含的必要元素
·HTTP不同版本之間的差異
·HTTP、Socket腥寇、TCP的區(qū)別(易混)

一成翩、HTTP協(xié)議

HTTP本質(zhì)上是一種協(xié)議,全稱是Hypertext Transfer Protocol赦役,即超文本傳輸協(xié)議麻敌。從名字上可以看出該協(xié)議用于規(guī)定客戶端與服務(wù)端之間的傳輸規(guī)則,所傳輸?shù)膬?nèi)容不局限于文本(其實(shí)可以傳輸任意類型的數(shù)據(jù))掂摔。

image

二术羔、HTTP請(qǐng)求與響應(yīng)的內(nèi)容

當(dāng)我們往服務(wù)端發(fā)送一條HTTP請(qǐng)求時(shí)都發(fā)送了哪些東西過去呢?
先看一個(gè)POST請(qǐng)求的示例圖:

image

注:本文使用Paw來模擬發(fā)送HTTP請(qǐng)求乙漓,使用Charles抓包级历,Charles選中"Request"以及"Raw"選項(xiàng)就可以看到請(qǐng)求的全部內(nèi)容

以上示例圖中其實(shí)已經(jīng)包含了一個(gè)HTTP請(qǐng)求所必備的幾大要素:請(qǐng)求行、請(qǐng)求頭(headerField)叭披、請(qǐng)求體(body)寥殖;同理,響應(yīng)也有狀態(tài)行涩蜘、響應(yīng)頭扛禽、實(shí)體內(nèi)容。接下來我們逐個(gè)展開皱坛。

1编曼、請(qǐng)求行

請(qǐng)求行包含請(qǐng)求方法(Method)、請(qǐng)求統(tǒng)一資源標(biāo)識(shí)符(URI)剩辟、HTTP版本號(hào)掐场,如圖2.1第一行所示:

image
  • 請(qǐng)求方法就是我們所熟悉的POST往扔、GET、HEAD熊户、PUT等
  • URI就是URL中排除掉Host剩下的部分萍膛,也就是資源在服務(wù)器本地上的路徑
  • HTTP版本號(hào),目前主流的版本是1.1(1999年開始采用)嚷堡,最新的版本是2.0(2015年5月發(fā)布)蝗罗。不同版本之間差異下面會(huì)再展開

2、請(qǐng)求頭

請(qǐng)求頭主要存放對(duì)客戶端想給服務(wù)端的附加信息蝌戒,下圖框框的部分就是請(qǐng)求頭:

image

HTTP請(qǐng)求在iOS中用NSURLRequestNSMutableRequest表示串塑;HTTP響應(yīng)用NSHTTPURLResponse表示。

  • Host: 目標(biāo)服務(wù)器的網(wǎng)絡(luò)地址
  • Accept: 讓服務(wù)端知道客戶端所能接收的數(shù)據(jù)類型北苟,如text/html */*
  • Content-Type: body中的數(shù)據(jù)類型桩匪,如application/json; charset=UTF-8
  • Accept-Language: 客戶端的語言環(huán)境,如zh-cn
  • Accept-Encoding: 客戶端支持的數(shù)據(jù)壓縮格式友鼻,如gzip
  • User-Agent: 客戶端的軟件環(huán)境傻昙,我們可以更改該字段為自己客戶端的名字,比如QQ music v1.11彩扔,比如瀏覽器Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Maxthon/4.5.2
  • Connection: keep-alive妆档,該字段是從HTTP 1.1才開始有的,用來告訴服務(wù)端這是一個(gè)持久連接虫碉,“請(qǐng)服務(wù)端不要在發(fā)出響應(yīng)后立即斷開TCP連接”过吻。關(guān)于該字段的更多解釋將在后面的HTTP版本簡介中展開。
  • Content-Length: body的長度蔗衡,如果body為空則該字段值為0纤虽。該字段一般在POST請(qǐng)求中才會(huì)有。

POST請(qǐng)求的body請(qǐng)求體也有可能是空的绞惦,因此POST中Content-Length也有可能為0

  • Cookie: 記錄者用戶信息的保存在本地的用戶數(shù)據(jù)逼纸,如果有會(huì)被自動(dòng)附上

值得一提的是,在iOS中當(dāng)你發(fā)送一個(gè)任意請(qǐng)求時(shí)济蝉,不管你愿不愿意杰刽,NSURLRequest都會(huì)自動(dòng)幫你記錄你所訪問的URL上設(shè)置的cookie。在iOS中用NSHTTPCookieStorage表示王滤,是一個(gè)單例贺嫂。通過```
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [cookieJar cookies]) {
NSLog(@"%@", cookie);
}

以上就是我們?nèi)粘i_發(fā)中比較經(jīng)常遇到的請(qǐng)求頭,其實(shí)還有其他的field雁乡,但篇幅所限無法一一列出第喳,想了解所有請(qǐng)求頭請(qǐng)看這里請(qǐng)求頭響應(yīng)頭列表。那在iOS中如何設(shè)置添加這些field呢踱稍?可以使用-[NSMutableURLRequest addValue: forHTTPHeaderField:]方法曲饱,獲取當(dāng)前請(qǐng)求已經(jīng)設(shè)置的field可以用-[NSURLRequest allHTTPHeaderFields]悠抹。也就是我們可以通過以上接口定制我們所需要的請(qǐng)求頭,但是有些field是不能改的扩淀,我們看一下iOS的描述:

圖2.4 iOS請(qǐng)求頭接口描述.png

從文檔中我們可以看到楔敌,在iOS中不應(yīng)當(dāng)對(duì)Authorization Connection Host WWW-Authenticate這幾個(gè)header field做更改。

3驻谆、請(qǐng)求體

真正需要發(fā)給服務(wù)端的數(shù)據(jù)卵凑,在使用POST-multipart上傳請(qǐng)求中請(qǐng)求體就是上傳文件的二進(jìn)制NSData類型數(shù)據(jù);在GET請(qǐng)求中請(qǐng)求體為空胜臊;在普通的POST請(qǐng)求中請(qǐng)求體就是一些表單數(shù)據(jù)勺卢。在iOS中一般用NSURLRequestNSMutableURLRequestHTTPBody屬性表示,添加body用-[NSMutableURLRequest setHTTPBody:]区端。

4、響應(yīng)狀態(tài)行

狀態(tài)行是服務(wù)端返回給客戶端的狀態(tài)信息澳腹,包含HTTP版本號(hào)织盼、狀態(tài)碼、狀態(tài)碼對(duì)應(yīng)的英文名稱酱塔。
以下就是典型的正確狀態(tài)行:
HTTP/1.1 200 OK
這個(gè)部分需要講的是錯(cuò)誤碼沥邻。事實(shí)上HTTP請(qǐng)求錯(cuò)誤碼可以根據(jù)錯(cuò)誤碼從左往右第一個(gè)數(shù)字大致分為以下幾類:

1XX:信息提示。不代表成功或者失敗羊娃,表示臨時(shí)響應(yīng)唐全,比如100表示繼續(xù),101表示切換協(xié)議
2XX: 成功
3XX: 重定向
4XX:客戶端錯(cuò)誤蕊玷,很有可能是客戶端發(fā)生問題邮利,如親切可愛的404表示未找到文件,說明你的URI是有問題的垃帅,服務(wù)器機(jī)子上該目錄是沒有該文件的延届;414URI太長
5XX: 服務(wù)器錯(cuò)誤,比如504網(wǎng)關(guān)超時(shí)

錯(cuò)誤碼是不用去記的贸诚,出錯(cuò)了再查對(duì)應(yīng)的錯(cuò)誤碼含義就行方庭。但是知道上面的分類有助于第一時(shí)間做出大體的判斷,起碼你能清楚是服務(wù)端還是客戶端的原因酱固。

5械念、響應(yīng)頭與響應(yīng)實(shí)體

這部分與請(qǐng)求部分差異不大,響應(yīng)頭的字field會(huì)有稍許不同运悲,響應(yīng)頭中的header field同樣移步請(qǐng)求頭響應(yīng)頭列表龄减。

三、HTTP版本簡介

這里我把HTTP版本簡單分為三類:1.1之前班眯,1.1欺殿,2.0寄纵,針對(duì)這三類做個(gè)主要差異的介紹:

HTTP 1.1之前

  • 不支持持久連接。一旦服務(wù)器對(duì)客戶端發(fā)出響應(yīng)就立即斷開TCP連接
  • 無請(qǐng)求頭跟響應(yīng)頭
  • 客戶端的前后請(qǐng)求是同步的脖苏。下一個(gè)請(qǐng)求必須等上一個(gè)請(qǐng)求從服務(wù)端拿到響應(yīng)后才能發(fā)出程拭,有點(diǎn)類似多線程的同步機(jī)制。

HTTP 1.1(主流版本)
與1.1之前的版本相比棍潘,做了以下性能上的提升

  • 增加請(qǐng)求頭跟響應(yīng)頭
  • 支持持久連接恃鞋。客戶端通過請(qǐng)求頭中指定Connectionkeep-alive告知服務(wù)端不要在完成響應(yīng)后立即釋放連接亦歉。HTTP是基于TCP的恤浪,在HTTP 1.1中一次TCP連接可以處理多次HTTP請(qǐng)求
  • 客戶端不同請(qǐng)求之間是異步的。下一個(gè)請(qǐng)求不必等到上一個(gè)請(qǐng)求回來后再發(fā)出肴楷,而可以連續(xù)發(fā)出請(qǐng)求水由,有點(diǎn)類似多線程的異步處理。

HTTP 2.0
本著向下兼容的原則赛蔫,1.1版本有的特性2.0都具備砂客,也使用相同的API。但是2.0將只用于https網(wǎng)址呵恢。由于2.0的普及還需要比較長的一段時(shí)間鞠值,這里不展開,更多新特性請(qǐng)參考這篇文章渗钉。

我們重點(diǎn)關(guān)注一下當(dāng)前1.1版本所做幾點(diǎn)改變彤恶。支持持久連接有什么好處呢?HTTP是基于TCP連接的鳄橘,如果連接被頻繁地啟動(dòng)然后斷開就會(huì)花費(fèi)很多資源在TCP三次握手以及四次揮手上声离,效率低下。以請(qǐng)求一個(gè)網(wǎng)頁為例瘫怜,我們知道抵恋,一個(gè)html網(wǎng)頁上的圖片資源并不是直接嵌入在網(wǎng)頁上,而只是提供url宝磨,圖片仍需要額外發(fā)HTTP 請(qǐng)求去下載弧关。一個(gè)網(wǎng)頁從請(qǐng)求到最終加載到本地往往需要經(jīng)過過個(gè)HTTP請(qǐng)求。在1.1版本之前請(qǐng)求一個(gè)網(wǎng)頁就需要發(fā)生多次"握手-揮手"的過程唤锉,每次連接之間相互獨(dú)立世囊;而1.1及之后的版本最少只需要一次就夠。
再來就是請(qǐng)求異步窿祥,其好處參考多線程異步處理株憾,在此不展開。
以上特性可以用圖2.3表示:

圖3.1 異步請(qǐng)求.jpg

我們可以看到:1、N次請(qǐng)求其實(shí)只建立了1次TCP連接嗤瞎,2墙歪、N次請(qǐng)求連續(xù)異步發(fā)出。

四贝奇、HTTP虹菲、Socket、TCP的區(qū)別

這三個(gè)概念經(jīng)常被談到掉瞳,也是比較容易被混淆的概念毕源。在回顧之前我們先看一下這三者在TCP/IP協(xié)議族中的位置關(guān)系:

圖4.1 層次關(guān)系.png

HTTP是應(yīng)用層的協(xié)議,更靠近用戶端陕习;TCP是傳輸層的協(xié)議霎褐;而socket是從傳輸層上抽象出來的一個(gè)抽象層,本質(zhì)是接口该镣。所以本質(zhì)上三種還是很好區(qū)分的冻璃。盡管如此,有時(shí)候你可能會(huì)懵逼损合,HTTP連接省艳、TCP連接、socket連接有什么區(qū)別塌忽?好吧拍埠,如果上面的圖解釋的還是不夠清楚的話失驶,我們繼續(xù)往下看土居。

1、TCP連接與HTTP連接的區(qū)別

上文提過嬉探,HTTP是基于TCP的擦耀,客戶端往服務(wù)端發(fā)送一個(gè)HTTP請(qǐng)求時(shí)第一步就是要建立與服務(wù)端的TCP連接,也就是先三次握手涩堤,“你好眷蜓,你好,你好”胎围。從HTTP 1.1開始支持持久連接吁系,也就是一次TCP連接可以發(fā)送多次的HTTP請(qǐng)求。
小總結(jié):HTTP基于TCP

2白魂、TCP連接與Socket連接的區(qū)別

在圖4.1中我們提到汽纤,socket層只是在TCP/UDP傳輸層上做的一個(gè)抽象接口層,因此一個(gè)socket連接可以基于TCP福荸,也有可能基于UDP蕴坪。基于TCP協(xié)議的socket連接同樣需要通過三次握手建立連接,是可靠的背传;基于UDP協(xié)議的socket連接不需要建立連接的過程呆瞻,不過對(duì)方能不能收到都會(huì)發(fā)送過去,是不可靠的径玖,大多數(shù)的即時(shí)通訊IM都是后者痴脾。
小總結(jié):Socket也可以基于TCP

3、HTTP連接與Socket連接的區(qū)別

區(qū)分這兩個(gè)概念是比較有意義的挺狰,畢竟TCP看不見摸不著明郭,HTTP與Socket是實(shí)實(shí)在在能用到的。

  • HTTP是短連接丰泊,Socket(基于TCP協(xié)議的)是長連接薯定。盡管HTTP1.1開始支持持久連接,但仍無法保證始終連接瞳购。而Socket連接一旦建立TCP三次握手话侄,除非一方主動(dòng)斷開,否則連接狀態(tài)一直保持学赛。
  • HTTP連接服務(wù)端無法主動(dòng)發(fā)消息年堆,Socket連接雙方請(qǐng)求的發(fā)送先后限制。這點(diǎn)就比較重要了盏浇,因?yàn)樗鼘Q定二者分別適合應(yīng)用在什么場景下变丧。HTTP采用“請(qǐng)求-響應(yīng)”機(jī)制,在客戶端還沒發(fā)送消息給服務(wù)端前绢掰,服務(wù)端無法推送消息給客戶端痒蓬。必須滿足客戶端發(fā)送消息在前,服務(wù)端回復(fù)在后滴劲。Socket連接雙方類似peer2peer的關(guān)系攻晒,一方隨時(shí)可以向另一方喊話闷堡。

4竹揍、問題來了:什么時(shí)候該用HTTP酿秸,什么時(shí)候該用socket

這個(gè)問題的提出是很自然而然的粤咪。當(dāng)你接到一個(gè)與另一方的網(wǎng)絡(luò)通訊需求才漆,自然會(huì)考慮用HTTP還是用Socket下翎。

  • 用HTTP的情況:雙方不需要時(shí)刻保持連接在線刁憋,比如客戶端資源的獲取珍昨、文件上傳等
  • 用Socket的情況:大部分即時(shí)通訊應(yīng)用(QQ双揪、微信)动羽、聊天室、蘋果APNs等

在iOS中盟榴,發(fā)HTTP請(qǐng)求一般用原生的NSURLConnection曹质、NSURLSession或者開源的AFNetWorking(推薦)ASIHttpRequest(已停止更新)。連接Socket連接我用的比較多是robbiehanson大神的CocoaAsyncSocket (XMPPFramework也是出自他手)羽德。

轉(zhuǎn)發(fā):https://blog.csdn.net/sandyloo/article/details/80180120

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末几莽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宅静,更是在濱河造成了極大的恐慌章蚣,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姨夹,死亡現(xiàn)場離奇詭異纤垂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)磷账,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門峭沦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逃糟,你說我怎么就攤上這事吼鱼。” “怎么了绰咽?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵菇肃,是天一觀的道長。 經(jīng)常有香客問我取募,道長琐谤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任玩敏,我火速辦了婚禮斗忌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘聊品。我一直安慰自己飞蹂,他們只是感情好几苍,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布翻屈。 她就那樣靜靜地躺著,像睡著了一般妻坝。 火紅的嫁衣襯著肌膚如雪伸眶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天刽宪,我揣著相機(jī)與錄音厘贼,去河邊找鬼。 笑死圣拄,一個(gè)胖子當(dāng)著我的面吹牛嘴秸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼岳掐,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼凭疮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起串述,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤执解,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纲酗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衰腌,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年觅赊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了右蕊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吮螺,死狀恐怖尤泽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情规脸,我是刑警寧澤坯约,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站莫鸭,受9級(jí)特大地震影響闹丐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜被因,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一卿拴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梨与,春花似錦堕花、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呻粹,卻和暖如春壕曼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背等浊。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工腮郊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筹燕。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓轧飞,卻偏偏與公主長得像衅鹿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子过咬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容