Post 和 Get 是 HTTP 請求的兩種方法,其區(qū)別如下:
HTTP Request Header 常見的請求頭:
HTTP Responses Header 常見的響應(yīng)頭:
常見的 Content-Type 屬性值有以下四種:
(1)application/x-www-form-urlencoded:瀏覽器的原生 form 表單,如果不設(shè)置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數(shù)據(jù)。該種方式提交的數(shù)據(jù)放在 body 里面,數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL轉(zhuǎn)碼。
(2)multipart/form-data:該種方式也是一個常見的 POST 提交方式,通常表單上傳文件時使用該種方式。
(3)application/json:服務(wù)器消息主體是序列化后的 JSON 字符串。
(4)text/xml:該種方式主要用來提交 XML 格式的數(shù)據(jù)。
服務(wù)器向客戶端發(fā)送數(shù)據(jù)格式類型:XML、HTML、JSON
服務(wù)器為了提高網(wǎng)站訪問速度,對之前訪問的部分頁面指定緩存機制,當(dāng)客戶端在此對這些頁面進行請求,服務(wù)器會根據(jù)緩存內(nèi)容判斷頁面與之前是否相同,若相同便直接返回304,此時客戶端調(diào)用緩存內(nèi)容,不必進行二次下載。
狀態(tài)碼304不應(yīng)該認為是一種錯誤,而是對客戶端有緩存情況下服務(wù)端的一種響應(yīng)。
搜索引擎蜘蛛會更加青睞內(nèi)容源更新頻繁的網(wǎng)站。通過特定時間內(nèi)對網(wǎng)站抓取返回的狀態(tài)碼來調(diào)節(jié)對該網(wǎng)站的抓取頻次。若網(wǎng)站在一定時間內(nèi)一直處于304的狀態(tài),那么蜘蛛可能會降低對網(wǎng)站的抓取次數(shù)。相反,若網(wǎng)站變化的頻率非常之快,每次抓取都能獲取新內(nèi)容,那么日積月累,的回訪率也會提高。
產(chǎn)生較多304狀態(tài)碼的原因:
304狀態(tài)碼出現(xiàn)過多會造成以下問題:
OPTIONS是除了GET和POST之外的其中一種 HTTP請求方法。
OPTIONS方法是用于請求獲得由 Request-URI
標(biāo)識的資源在請求/響應(yīng)的通信過程中可以使用的功能選項。通過這個方法,客戶端可以在采取具體資源請求之前,決定對該資源采取何種必要措施,或者了解服務(wù)器的性能。該請求方法的響應(yīng)不能緩存。
OPTIONS請求方法的主要用途有兩個:
HTTP 1.0和 HTTP 1.1 有以下區(qū)別:
【1】隊頭堵塞:
隊頭阻塞是由 HTTP 基本的“請求 - 應(yīng)答”模型所導(dǎo)致的。HTTP 規(guī)定報文必須是“一發(fā)一收”,這就形成了一個先進先出的“串行”隊列。隊列里的請求是沒有優(yōu)先級的,只有入隊的先后順序,排在最前面的請求會被最優(yōu)先處理。如果隊首的請求因為處理的太慢耽誤了時間,那么隊列里后面的所有請求也不得不跟著一起等待,結(jié)果就是其他的請求承擔(dān)了不應(yīng)有的時間成本,造成了隊頭堵塞的現(xiàn)象。
HTTP和HTTPS協(xié)議的主要區(qū)別如下:
實際上HTTP協(xié)議規(guī)范并沒有對get方法請求的url長度進行限制,這個限制是特定的瀏覽器及服務(wù)器對它的限制。
IE對URL長度的限制是2083字節(jié)(2K+35)。由于IE瀏覽器對URL長度的允許值是最小的,所以開發(fā)過程中,只要URL不超過2083字節(jié),那么在所有瀏覽器中工作都不會有問題。
GET的長度值 = URL(2083)- (你的Domain+Path)-2(2是get請求中?=兩個字符的長度)
下面看一下主流瀏覽器對get方法中url的長度限制范圍:
主流的服務(wù)器對get方法中url的長度限制范圍:
根據(jù)上面的數(shù)據(jù),可以知道,get方法中的URL長度最長不超過2083個字符,這樣所有的瀏覽器和服務(wù)器都可能正常工作。
(1)解析URL:首先會對 URL 進行解析,分析所需要使用的傳輸協(xié)議和請求的資源的路徑。如果輸入的 URL 中的協(xié)議或者主機名不合法,將會把地址欄中輸入的內(nèi)容傳遞給搜索引擎。如果沒有問題,瀏覽器會檢查 URL 中是否出現(xiàn)了非法字符,如果存在非法字符,則對非法字符進行轉(zhuǎn)義后再進行下一過程。
(2)緩存判斷:瀏覽器會判斷所請求的資源是否在緩存里,如果請求的資源在緩存里并且沒有失效,那么就直接使用,否則向服務(wù)器發(fā)起新的請求。
(3)DNS解析:下一步首先需要獲取的是輸入的 URL 中的域名的 IP 地址,首先會判斷本地是否有該域名的 IP 地址的緩存,如果有則使用,如果沒有則向本地 DNS 服務(wù)器發(fā)起請求。本地 DNS 服務(wù)器也會先檢查是否存在緩存,如果沒有就會先向根域名服務(wù)器發(fā)起請求,獲得負責(zé)的頂級域名服務(wù)器的地址后,再向頂級域名服務(wù)器請求,然后獲得負責(zé)的權(quán)威域名服務(wù)器的地址后,再向權(quán)威域名服務(wù)器發(fā)起請求,最終獲得域名的 IP 地址后,本地 DNS 服務(wù)器再將這個 IP 地址返回給請求的用戶。用戶向本地 DNS 服務(wù)器發(fā)起請求屬于遞歸請求,本地 DNS 服務(wù)器向各級域名服務(wù)器發(fā)起請求屬于迭代請求。
(4)獲取MAC地址:當(dāng)瀏覽器得到 IP 地址后,數(shù)據(jù)傳輸還需要知道目的主機 MAC 地址,因為應(yīng)用層下發(fā)數(shù)據(jù)給傳輸層,TCP 協(xié)議會指定源端口號和目的端口號,然后下發(fā)給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層會將本機地址作為源地址,獲取的 IP 地址作為目的地址。然后將下發(fā)給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層的發(fā)送需要加入通信雙方的 MAC 地址,本機的 MAC 地址作為源 MAC 地址,目的 MAC 地址需要分情況處理。通過將 IP 地址與本機的子網(wǎng)掩碼相與,可以判斷是否與請求主機在同一個子網(wǎng)里,如果在同一個子網(wǎng)里,可以使用 ARP 協(xié)議獲取到目的主機的 MAC 地址,如果不在一個子網(wǎng)里,那么請求應(yīng)該轉(zhuǎn)發(fā)給網(wǎng)關(guān),由它代為轉(zhuǎn)發(fā),此時同樣可以通過 ARP 協(xié)議來獲取網(wǎng)關(guān)的 MAC 地址,此時目的主機的 MAC 地址應(yīng)該為網(wǎng)關(guān)的地址。
(5)TCP三次握手:下面是 TCP 建立連接的三次握手的過程,首先客戶端向服務(wù)器發(fā)送一個 SYN 連接請求報文段和一個隨機序號,服務(wù)端接收到請求后向服務(wù)器端發(fā)送一個 SYN ACK報文段,確認連接請求,并且也向客戶端發(fā)送一個隨機序號??蛻舳私邮辗?wù)器的確認應(yīng)答后,進入連接建立的狀態(tài),同時向服務(wù)器也發(fā)送一個ACK 確認報文段,服務(wù)器端接收到確認后,也進入連接建立狀態(tài),此時雙方的連接就建立起來了。
(6)HTTPS握手:如果使用的是 HTTPS 協(xié)議,在通信前還存在 TLS 的一個四次握手的過程。首先由客戶端向服務(wù)器端發(fā)送使用的協(xié)議的版本號、一個隨機數(shù)和可以使用的加密方法。服務(wù)器端收到后,確認加密的方法,也向客戶端發(fā)送一個隨機數(shù)和自己的數(shù)字證書??蛻舳耸盏胶?,首先檢查數(shù)字證書是否有效,如果有效,則再生成一個隨機數(shù),并使用證書中的公鑰對隨機數(shù)加密,然后發(fā)送給服務(wù)器端,并且還會提供一個前面所有內(nèi)容的 hash 值供服務(wù)器端檢驗。服務(wù)器端接收后,使用自己的私鑰對數(shù)據(jù)解密,同時向客戶端發(fā)送一個前面所有內(nèi)容的 hash 值供客戶端檢驗。這個時候雙方都有了三個隨機數(shù),按照之前所約定的加密方法,使用這三個隨機數(shù)生成一把秘鑰,以后雙方通信前,就使用這個秘鑰對數(shù)據(jù)進行加密后再傳輸。
(7)返回數(shù)據(jù):當(dāng)頁面請求發(fā)送到服務(wù)器端后,服務(wù)器端會返回一個 html 文件作為響應(yīng),瀏覽器接收到響應(yīng)后,開始對 html 文件進行解析,開始頁面的渲染過程。
(8)頁面渲染:瀏覽器首先會根據(jù) html 文件構(gòu)建 DOM 樹,根據(jù)解析到的 css 文件構(gòu)建 CSSOM 樹,如果遇到 script 標(biāo)簽,則判端是否含有 defer 或者 async 屬性,要不然 script 的加載和執(zhí)行會造成頁面的渲染的阻塞。當(dāng) DOM 樹和 CSSOM 樹建立好后,根據(jù)它們來構(gòu)建渲染樹。渲染樹構(gòu)建好后,會根據(jù)渲染樹來進行布局。布局完成后,最后使用瀏覽器的 UI 接口對頁面進行繪制。這個時候整個頁面就顯示出來了。
(9)TCP四次揮手:最后一步是 TCP 斷開連接的四次揮手過程。若客戶端認為數(shù)據(jù)發(fā)送完成,則它需要向服務(wù)端發(fā)送連接釋放請求。服務(wù)端收到連接釋放請求后,會告訴應(yīng)用層要釋放 TCP 鏈接。然后會發(fā)送 ACK 包,并進入 CLOSE_WAIT 狀態(tài),此時表明客戶端到服務(wù)端的連接已經(jīng)釋放,不再接收客戶端發(fā)的數(shù)據(jù)了。但是因為 TCP 連接是雙向的,所以服務(wù)端仍舊可以發(fā)送數(shù)據(jù)給客戶端。服務(wù)端如果此時還有沒發(fā)完的數(shù)據(jù)會繼續(xù)發(fā)送,完畢后會向客戶端發(fā)送連接釋放請求,然后服務(wù)端便進入 LAST-ACK 狀態(tài)??蛻舳耸盏结尫耪埱蠛螅蚍?wù)端發(fā)送確認應(yīng)答,此時客戶端進入 TIME-WAIT 狀態(tài)。該狀態(tài)會持續(xù) 2MSL(最大段生存期,指報文段在網(wǎng)絡(luò)中生存的時間,超時會被拋棄) 時間,若該時間段內(nèi)沒有服務(wù)端的重發(fā)請求的話,就進入 CLOSED 狀態(tài)。當(dāng)服務(wù)端收到確認應(yīng)答后,也便進入 CLOSED 狀態(tài)。
HTTP1.0 中默認是在每次請求/應(yīng)答,客戶端和服務(wù)器都要新建一個連接,完成之后立即斷開連接,這就是短連接。當(dāng)使用Keep-Alive模式時,Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接,這就是長連接。其使用方法如下:
Connection: keep-alive
?字段。若想斷開keep-alive連接,需發(fā)送 ?Connection:close
?字段;Connection:close
?首部字段。Keep-Alive的建立過程:
服務(wù)端自動斷開過程(也就是沒有keep-alive):
客戶端請求斷開連接過程:
開啟Keep-Alive的優(yōu)點:
開啟Keep-Alive的缺點:
HTTP2的頭部壓縮是HPACK算法。在客戶端和服務(wù)器兩端建立“字典”,用索引號表示重復(fù)的字符串,采用哈夫曼編碼來壓縮整數(shù)和字符串,可以達到50%~90%的高壓縮率。
具體來說:
例如下圖中的兩個請求, 請求一發(fā)送了所有的頭部字段,第二個請求則只需要發(fā)送差異數(shù)據(jù),這樣可以減少冗余數(shù)據(jù),降低開銷。
請求報?有4部分組成:
其中:
(1)請求?包括:請求?法字段、URL字段、HTTP協(xié)議版本字段。它們?空格分隔。例如,GET /index.html HTTP/1.1。
(2)請求頭部:請求頭部由關(guān)鍵字/值對組成,每??對,關(guān)鍵字和值?英?冒號“:”分隔
(3)請求體: post put等請求攜帶的數(shù)據(jù)
請求報?有4部分組成:
HTTP 是超文本傳輸協(xié)議,它定義了客戶端和服務(wù)器之間交換報文的格式和方式,默認使用 80 端口。它使用 TCP 作為傳輸層協(xié)議,保證了數(shù)據(jù)傳輸?shù)目煽啃浴?
HTTP協(xié)議具有以下優(yōu)點:
HTTP協(xié)議具有以下缺點:
(1)通信使用明文(不加密),內(nèi)容可能會被竊聽;
(2)不驗證通信方的身份,因此有可能遭遇偽裝;
(3)無法證明報文的完整性,所以有可能已遭篡改;
HTTP/3基于UDP協(xié)議實現(xiàn)了類似于TCP的多路復(fù)用數(shù)據(jù)流、傳輸可靠性等功能,這套功能被稱為QUIC協(xié)議。
HTTP 協(xié)議是基于 TCP/IP,并且使用了請求-應(yīng)答的通信模式,所以性能的關(guān)鍵就在這兩點里。
HTTP協(xié)議有兩種連接模式,一種是持續(xù)連接,一種非持續(xù)連接。
(1)非持續(xù)連接指的是服務(wù)器必須為每一個請求的對象建立和維護一個全新的連接。
(2)持續(xù)連接下,TCP 連接默認不關(guān)閉,可以被多個請求復(fù)用。采用持續(xù)連接的好處是可以避免每次建立 TCP 連接三次握手時所花費的時間。
對于不同版本的采用不同的連接方式:
HTTP/1.1 采用了長連接的方式,這使得管道(pipeline)網(wǎng)絡(luò)傳輸成為了可能。
管道(pipeline)網(wǎng)絡(luò)傳輸是指:可以在同一個 TCP 連接里面,客戶端可以發(fā)起多個請求,只要第一個請求發(fā)出去了,不必等其回來,就可以發(fā)第二個請求出去,可以減少整體的響應(yīng)時間。但是服務(wù)器還是按照順序回應(yīng)請求。如果前面的回應(yīng)特別慢,后面就會有許多請求排隊等著。這稱為隊頭堵塞。
HTTP 傳輸?shù)膱笪谋仨毷且话l(fā)一收,但是,里面的任務(wù)被放在一個任務(wù)隊列中串行執(zhí)行,一旦隊首的請求處理太慢,就會阻塞后面請求的處理。這就是HTTP隊頭阻塞問題。
隊頭阻塞的解決方案:
(1)并發(fā)連接:對于一個域名允許分配多個長連接,那么相當(dāng)于增加了任務(wù)隊列,不至于一個隊伍的任務(wù)阻塞其它所有任務(wù)。
(2)域名分片:將域名分出很多二級域名,它們都指向同樣的一臺服務(wù)器,能夠并發(fā)的長連接數(shù)變多,解決了隊頭阻塞的問題。
以下面的URL為例:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
從上面的URL可以看出,一個完整的URL包括以下幾部分:
強緩存:
協(xié)商緩存:
超文本傳輸安全協(xié)議(Hypertext Transfer Protocol Secure,簡稱:HTTPS)是一種通過計算機網(wǎng)絡(luò)進行安全通信的傳輸協(xié)議。HTTPS經(jīng)由HTTP進行通信,利用SSL/TLS來加密數(shù)據(jù)包。HTTPS的主要目的是提供對網(wǎng)站服務(wù)器的身份認證,保護交換數(shù)據(jù)的隱私與完整性。
HTTP協(xié)議采用明文傳輸信息,存在信息竊聽、信息篡改和信息劫持的風(fēng)險,而協(xié)議TLS/SSL具有身份驗證、信息加密和完整性校驗的功能,可以避免此類問題發(fā)生。
安全層的主要職責(zé)就是對發(fā)起的HTTP請求的數(shù)據(jù)進行加密操作 和 對接收到的HTTP的內(nèi)容進行解密操作。
TLS/SSL全稱安全傳輸層協(xié)議(Transport Layer Security), 是介于TCP和HTTP之間的一層安全協(xié)議,不影響原有的TCP協(xié)議和HTTP協(xié)議,所以使用HTTPS基本上不需要對HTTP頁面進行太多的改造。
TLS/SSL的功能實現(xiàn)主要依賴三類基本算法:散列函數(shù)hash、對稱加密、非對稱加密。這三類算法的作用如下:
常見的散列函數(shù)有MD5、SHA1、SHA256。該函數(shù)的特點是單向不可逆,對輸入數(shù)據(jù)非常敏感,輸出的長度固定,任何數(shù)據(jù)的修改都會改變散列函數(shù)的結(jié)果,可以用于防止信息篡改并驗證數(shù)據(jù)的完整性。
特點:在信息傳輸過程中,散列函數(shù)不能三都實現(xiàn)信息防篡改,由于傳輸是明文傳輸,中間人可以修改信息后重新計算信息的摘要,所以需要對傳輸?shù)男畔⒑托畔⒄M行加密。
對稱加密的方法是,雙方使用同一個秘鑰對數(shù)據(jù)進行加密和解密。但是對稱加密的存在一個問題,就是如何保證秘鑰傳輸?shù)陌踩?,因為秘鑰還是會通過網(wǎng)絡(luò)傳輸?shù)?,一旦秘鑰被其他人獲取到,那么整個加密過程就毫無作用了。 這就要用到非對稱加密的方法。
常見的對稱加密算法有AES-CBC、DES、3DES、AES-GCM等。相同的秘鑰可以用于信息的加密和解密。掌握秘鑰才能獲取信息,防止信息竊聽,其通訊方式是一對一。
特點:對稱加密的優(yōu)勢就是信息傳輸使用一對一,需要共享相同的密碼,密碼的安全是保證信息安全的基礎(chǔ),服務(wù)器和N個客戶端通信,需要維持N個密碼記錄且不能修改密碼。
非對稱加密的方法是,我們擁有兩個秘鑰,一個是公鑰,一個是私鑰。公鑰是公開的,私鑰是保密的。用私鑰加密的數(shù)據(jù),只有對應(yīng)的公鑰才能解密,用公鑰加密的數(shù)據(jù),只有對應(yīng)的私鑰才能解密。我們可以將公鑰公布出去,任何想和我們通信的客戶, 都可以使用我們提供的公鑰對數(shù)據(jù)進行加密,這樣我們就可以使用私鑰進行解密,這樣就能保證數(shù)據(jù)的安全了。但是非對稱加密有一個缺點就是加密的過程很慢,因此如果每次通信都使用非對稱加密的方式的話,反而會造成等待時間過長的問題。
常見的非對稱加密算法有RSA、ECC、DH等。秘鑰成對出現(xiàn),一般稱為公鑰(公開)和私鑰(保密)。公鑰加密的信息只有私鑰可以解開,私鑰加密的信息只能公鑰解開,因此掌握公鑰的不同客戶端之間不能相互解密信息,只能和服務(wù)器進行加密通信,服務(wù)器可以實現(xiàn)一對多的的通信,客戶端也可以用來驗證掌握私鑰的服務(wù)器的身份。
特點:非對稱加密的特點就是信息一對多,服務(wù)器只需要維持一個私鑰就可以和多個客戶端進行通信,但服務(wù)器發(fā)出的信息能夠被所有的客戶端解密,且該算法的計算復(fù)雜,加密的速度慢。
綜合上述算法特點,TLS/SSL的工作方式就是客戶端使用非對稱加密與服務(wù)器進行通信,實現(xiàn)身份的驗證并協(xié)商對稱加密使用的秘鑰。對稱加密算法采用協(xié)商秘鑰對信息以及信息摘要進行加密通信,不同節(jié)點之間采用的對稱秘鑰不同,從而保證信息只能通信雙方獲取。這樣就解決了兩個方法各自存在的問題。
現(xiàn)在的方法也不一定是安全的,因為沒有辦法確定得到的公鑰就一定是安全的公鑰??赡艽嬖谝粋€中間人,截取了對方發(fā)給我們的公鑰,然后將他自己的公鑰發(fā)送給我們,當(dāng)我們使用他的公鑰加密后發(fā)送的信息,就可以被他用自己的私鑰解密。然后他偽裝成我們以同樣的方法向?qū)Ψ桨l(fā)送信息,這樣我們的信息就被竊取了,然而自己還不知道。為了解決這樣的問題,可以使用數(shù)字證書。
首先使用一種 Hash 算法來對公鑰和其他信息進行加密,生成一個信息摘要,然后讓有公信力的認證中心(簡稱 CA )用它的私鑰對消息摘要加密,形成簽名。最后將原始的信息和簽名合在一起,稱為數(shù)字證書。當(dāng)接收方收到數(shù)字證書的時候,先根據(jù)原始信息使用同樣的 Hash 算法生成一個摘要,然后使用公證處的公鑰來對數(shù)字證書中的摘要進行解密,最后將解密的摘要和生成的摘要進行對比,就能發(fā)現(xiàn)得到的信息是否被更改了。
這個方法最要的是認證中心的可靠性,一般瀏覽器里會內(nèi)置一些頂層的認證中心的證書,相當(dāng)于我們自動信任了他們,只有這樣才能保證數(shù)據(jù)的安全。
HTTPS的通信過程如下:
HTTPS的優(yōu)點如下:
HTTPS的缺點如下:
先理解兩個概念:
\1. 私鑰 + 公鑰= 密鑰對
\2. 即?私鑰加密的數(shù)據(jù),只有對應(yīng)的公鑰才能解密,?公鑰加密的數(shù)據(jù),只有對應(yīng)的私鑰才能解密
\3. 因為通信雙?的??都有?套??的密鑰對,通信之前雙?會先把??的公鑰都先發(fā)給對?
\4. 然后對?再拿著這個公鑰來加密數(shù)據(jù)響應(yīng)給對?,等到到了對?那?,對?再???的私鑰進?解密
?對稱加密雖然安全性更?,但是帶來的問題就是速度很慢,影響性能。
解決?案:
結(jié)合兩種加密?式,將對稱加密的密鑰使??對稱加密的公鑰進?加密,然后發(fā)送出去,接收?使?私鑰進?解密得到對稱加密的密鑰,然后雙?可以使?對稱加密來進?溝通。
此時?帶來?個問題,中間?問題:
如果此時在客戶端和服務(wù)器之間存在?個中間?,這個中間?只需要把原本雙?通信互發(fā)的公鑰,換成??的公鑰,這樣中間?就可以輕松解密通信雙?所發(fā)送的所有數(shù)據(jù)。
所以這個時候需要?個安全的第三?頒發(fā)證書(CA),證明身份的身份,防?被中間?攻擊。 證書中包括:簽發(fā)者、證書?途、使?者公鑰、使?者私鑰、使?者的HASH算法、證書到期時間等。
但是問題來了,如果中間?篡改了證書,那么身份證明是不是就?效了?這個證明就?買了,這個時候需要?個新的技術(shù),數(shù)字簽名。
數(shù)字簽名就是?CA?帶的HASH算法對證書的內(nèi)容進?HASH得到?個摘要,再?CA的私鑰加密,最終組成數(shù)字簽名。當(dāng)別?把他的證書發(fā)過來的時候,我再?同樣的Hash算法,再次?成消息摘要,然后?CA的公鑰對數(shù)字簽名解密,得到CA創(chuàng)建的消息摘要,兩者??,就知道中間有沒有被?篡改了。這個時候就能最?程度保證通信的安全了。
狀態(tài)碼的類別:
類別 | 原因 | 描述 |
---|---|---|
1xx | Informational(信息性狀態(tài)碼) | 接受的請求正在處理 |
2xx | Success(成功狀態(tài)碼) | 請求正常處理完畢 |
3xx | Redirection(重定向狀態(tài)碼) | 需要進行附加操作一完成請求 |
4xx | Client Error (客戶端錯誤狀態(tài)碼) | 服務(wù)器無法處理請求 |
5xx | Server Error(服務(wù)器錯誤狀態(tài)碼) | 服務(wù)器處理請求出錯 |
狀態(tài)碼2XX表示請求被正常處理了。
200 OK表示客戶端發(fā)來的請求被服務(wù)器端正常處理了。
該狀態(tài)碼表示客戶端發(fā)送的請求已經(jīng)在服務(wù)器端正常處理了,但是沒有返回的內(nèi)容,響應(yīng)報文中不包含實體的主體部分。一般在只需要從客戶端往服務(wù)器端發(fā)送信息,而服務(wù)器端不需要往客戶端發(fā)送內(nèi)容時使用。
該狀態(tài)碼表示客戶端進行了范圍請求,而服務(wù)器端執(zhí)行了這部分的 GET 請求。響應(yīng)報文中包含由 Content-Range 指定范圍的實體內(nèi)容。
3XX 響應(yīng)結(jié)果表明瀏覽器需要執(zhí)行某些特殊的處理以正確處理請求。
永久重定向。
該狀態(tài)碼表示請求的資源已經(jīng)被分配了新的 URI,以后應(yīng)使用資源指定的 URI。新的 URI 會在 HTTP 響應(yīng)頭中的 Location 首部字段指定。若用戶已經(jīng)把原來的URI保存為書簽,此時會按照 Location 中新的URI重新保存該書簽。同時,搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址替換為重定向之后的網(wǎng)址。
使用場景:
臨時重定向。
該狀態(tài)碼表示請求的資源被分配到了新的 URI,希望用戶(本次)能使用新的 URI 訪問資源。和 301 Moved Permanently 狀態(tài)碼相似,但是 302 代表的資源不是被永久重定向,只是臨時性質(zhì)的。也就是說已移動的資源對應(yīng)的 URI 將來還有可能發(fā)生改變。若用戶把 URI 保存成書簽,但不會像 301 狀態(tài)碼出現(xiàn)時那樣去更新書簽,而是仍舊保留返回 302 狀態(tài)碼的頁面對應(yīng)的 URI。同時,搜索引擎會抓取新的內(nèi)容而保留舊的網(wǎng)址。因為服務(wù)器返回302代碼,搜索引擎認為新的網(wǎng)址只是暫時的。
使用場景:
該狀態(tài)碼表示由于請求對應(yīng)的資源存在著另一個 URI,應(yīng)使用 GET 方法定向獲取請求的資源。
303 狀態(tài)碼和 302 Found 狀態(tài)碼有著相似的功能,但是 303 狀態(tài)碼明確表示客戶端應(yīng)當(dāng)采用 GET 方法獲取資源。
303 狀態(tài)碼通常作為 PUT 或 POST 操作的返回結(jié)果,它表示重定向鏈接指向的不是新上傳的資源,而是另外一個頁面,比如消息確認頁面或上傳進度頁面。而請求重定向頁面的方法要總是使用 GET。
注意:
瀏覽器緩存相關(guān)。
該狀態(tài)碼表示客戶端發(fā)送附帶條件的請求時,服務(wù)器端允許請求訪問資源,但未滿足條件的情況。304 狀態(tài)碼返回時,不包含任何響應(yīng)的主體部分。304 雖然被劃分在 3XX 類別中,但是和重定向沒有關(guān)系。
帶條件的請求(Http 條件請求):使用 Get方法 請求,請求報文中包含(if-match
、if-none-match
、if-modified-since
、if-unmodified-since
、if-range
)中任意首部。
狀態(tài)碼304并不是一種錯誤,而是告訴客戶端有緩存,直接使用緩存中的數(shù)據(jù)。返回頁面的只有頭部信息,是沒有內(nèi)容部分的,這樣在一定程度上提高了網(wǎng)頁的性能。
307表示臨時重定向。該狀態(tài)碼與 302 Found 有著相同含義,盡管 302 標(biāo)準(zhǔn)禁止 POST 變成 GET,但是實際使用時還是這樣做了。
307 會遵守瀏覽器標(biāo)準(zhǔn),不會從 POST 變成 GET。但是對于處理請求的行為時,不同瀏覽器還是會出現(xiàn)不同的情況。規(guī)范要求瀏覽器繼續(xù)向 Location 的地址 POST 內(nèi)容。規(guī)范要求瀏覽器繼續(xù)向 Location 的地址 POST 內(nèi)容。
4XX 的響應(yīng)結(jié)果表明客戶端是發(fā)生錯誤的原因所在。
該狀態(tài)碼表示請求報文中存在語法錯誤。當(dāng)錯誤發(fā)生時,需修改請求的內(nèi)容后再次發(fā)送請求。另外,瀏覽器會像 200 OK 一樣對待該狀態(tài)碼。
該狀態(tài)碼表示發(fā)送的請求需要有通過 HTTP 認證(BASIC 認證、DIGEST 認證)的認證信息。若之前已進行過一次請求,則表示用戶認證失敗
返回含有 401 的響應(yīng)必須包含一個適用于被請求資源的 WWW-Authenticate 首部用以質(zhì)詢(challenge)用戶信息。當(dāng)瀏覽器初次接收到 401 響應(yīng),會彈出認證用的對話窗口。
以下情況會出現(xiàn)401:
該狀態(tài)碼表明請求資源的訪問被服務(wù)器拒絕了,服務(wù)器端沒有必要給出詳細理由,但是可以在響應(yīng)報文實體的主體中進行說明。進入該狀態(tài)后,不能再繼續(xù)進行驗證。該訪問是永久禁止的,并且與應(yīng)用邏輯密切相關(guān)。
IIS 定義了許多不同的 403 錯誤,它們指明更為具體的錯誤原因:
該狀態(tài)碼表明服務(wù)器上無法找到請求的資源。除此之外,也可以在服務(wù)器端拒絕請求且不想說明理由時使用。
以下情況會出現(xiàn)404:
該狀態(tài)碼表示客戶端請求的方法雖然能被服務(wù)器識別,但是服務(wù)器禁止使用該方法。GET 和 HEAD 方法,服務(wù)器應(yīng)該總是允許客戶端進行訪問??蛻舳丝梢酝ㄟ^ OPTIONS 方法(預(yù)檢)來查看服務(wù)器允許的訪問方法, 如下
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
5XX 的響應(yīng)結(jié)果表明服務(wù)器本身發(fā)生錯誤.
該狀態(tài)碼表明服務(wù)器端在執(zhí)行請求時發(fā)生了錯誤。也有可能是 Web 應(yīng)用存在的 bug 或某些臨時的故障。
該狀態(tài)碼表明扮演網(wǎng)關(guān)或代理角色的服務(wù)器,從上游服務(wù)器中接收到的響應(yīng)是無效的。注意,502 錯誤通常不是客戶端能夠修復(fù)的,而是需要由途經(jīng)的 Web 服務(wù)器或者代理服務(wù)器對其進行修復(fù)。以下情況會出現(xiàn)502:
該狀態(tài)碼表明服務(wù)器暫時處于超負載或正在進行停機維護,現(xiàn)在無法處理請求。如果事先得知解除以上狀況需要的時間,最好寫入 RetryAfter 首部字段再返回給客戶端。
使用場景:
該狀態(tài)碼表示網(wǎng)關(guān)或者代理的服務(wù)器無法在規(guī)定的時間內(nèi)獲得想要的響應(yīng)。他是HTTP 1.1中新加入的。
使用場景:代碼執(zhí)行時間超時,或者發(fā)生了死循環(huán)。
(1)2XX 成功
(2)3XX 重定向
(3)4XX 客戶端錯誤
(4)5XX 服務(wù)器錯誤
302是http1.0的協(xié)議狀態(tài)碼,在http1.1版本的時候為了細化302狀態(tài)碼?出來了兩個303和307。 303明確表示客戶端應(yīng)當(dāng)采?get?法獲取資源,他會把POST請求變?yōu)镚ET請求進?重定向。 307會遵照瀏覽器標(biāo)準(zhǔn),不會從post變?yōu)間et。
概念: DNS 是域名系統(tǒng) (Domain Name System) 的縮寫,提供的是一種主機名到 IP 地址的轉(zhuǎn)換服務(wù),就是我們常說的域名系統(tǒng)。它是一個由分層的 DNS 服務(wù)器組成的分布式數(shù)據(jù)庫,是定義了主機如何查詢這個分布式數(shù)據(jù)庫的方式的應(yīng)用層協(xié)議。能夠使人更方便的訪問互聯(lián)網(wǎng),而不用去記住能夠被機器直接讀取的IP數(shù)串。
作用: 將域名解析為IP地址,客戶端向DNS服務(wù)器(DNS服務(wù)器有自己的IP地址)發(fā)送域名查詢請求,DNS服務(wù)器告知客戶機Web服務(wù)器的 IP 地址。
DNS占用53號端口,同時使用TCP和UDP協(xié)議。
(1)在區(qū)域傳輸?shù)臅r候使用TCP協(xié)議
(2)在域名解析的時候使用UDP協(xié)議
DNS服務(wù)器解析域名的過程:
比如要查詢 www.baidu.com 的 IP 地址,首先會在瀏覽器的緩存中查找是否有該域名的緩存,如果不存在就將請求發(fā)送到本地的 DNS 服務(wù)器中,本地DNS服務(wù)器會判斷是否存在該域名的緩存,如果不存在,則向根域名服務(wù)器發(fā)送一個請求,根域名服務(wù)器返回負責(zé) .com 的頂級域名服務(wù)器的 IP 地址的列表。然后本地 DNS 服務(wù)器再向其中一個負責(zé) .com 的頂級域名服務(wù)器發(fā)送一個請求,負責(zé) .com 的頂級域名服務(wù)器返回負責(zé) .baidu 的權(quán)威域名服務(wù)器的
IP 地址列表。然后本地 DNS 服務(wù)器再向其中一個權(quán)威域名服務(wù)器發(fā)送一個請求,最后權(quán)威域名服務(wù)器返回一個對應(yīng)的主機名的 IP 地址列表。
實際上,DNS解析是一個包含迭代查詢和遞歸查詢的過程。
一般我們向本地 DNS 服務(wù)器發(fā)送請求的方式就是遞歸查詢,因為我們只需要發(fā)出一次請求,然后本地 DNS 服務(wù)器返回給我 們最終的請求結(jié)果。而本地 DNS 服務(wù)器向其他域名服務(wù)器請求的過程是迭代查詢的過程,因為每一次域名服務(wù)器只返回單次 查詢的結(jié)果,下一級的查詢由本地 DNS 服務(wù)器自己進行。
DNS 服務(wù)器中以資源記錄的形式存儲信息,每一個 DNS 響應(yīng)報文一般包含多條資源記錄。一條資源記錄的具體的格式為
(Name,Value,Type,TTL)
其中 TTL 是資源記錄的生存時間,它定義了資源記錄能夠被其他的 DNS 服務(wù)器緩存多長時間。
常用的一共有四種 Type 的值,分別是 A、NS、CNAME 和 MX ,不同 Type 的值,對應(yīng)資源記錄代表的意義不同:
ISO
為了更好的使網(wǎng)絡(luò)應(yīng)用更為普及,推出了 OSI
參考模型。
OSI
參考模型中最靠近用戶的一層,是為計算機用戶提供應(yīng)用接口,也為用戶直接提供各種網(wǎng)絡(luò)服務(wù)。我們常見應(yīng)用層的網(wǎng)絡(luò)服務(wù)協(xié)議有:HTTP
,HTTPS
,FTP
,POP3
、SMTP
等。
http(hyper text transfer protocol)(超文本傳輸協(xié)議)
?或者 ?https
?在后端設(shè)計數(shù)據(jù)接口時,我們常常使用到這個協(xié)議。FTP
?是文件傳輸協(xié)議,在開發(fā)過程中,個人并沒有涉及到,但是我想,在一些資源網(wǎng)站,比如 百度網(wǎng)盤 迅雷應(yīng)該是基于此協(xié)議的。SMTP
?是 ?simple mail transfer protocol(簡單郵件傳輸協(xié)議)
?。在一個項目中,在用戶郵箱驗證碼登錄的功能時,使用到了這個協(xié)議。表示層提供各種用于應(yīng)用層數(shù)據(jù)的編碼和轉(zhuǎn)換功能,確保一個系統(tǒng)的應(yīng)用層發(fā)送的數(shù)據(jù)能被另一個系統(tǒng)的應(yīng)用層識別。如果必要,該層可提供一種標(biāo)準(zhǔn)表示形式,用于將計算機內(nèi)部的多種數(shù)據(jù)格式轉(zhuǎn)換成通信中采用的標(biāo)準(zhǔn)表示形式。數(shù)據(jù)壓縮和加密也是表示層可提供的轉(zhuǎn)換功能之一。
在項目開發(fā)中,為了方便數(shù)據(jù)傳輸,可以使用 base64
對數(shù)據(jù)進行編解碼。如果按功能來劃分,base64
應(yīng)該是工作在表示層。
會話層就是負責(zé)建立、管理和終止表示層實體之間的通信會話。該層的通信由不同設(shè)備中的應(yīng)用程序之間的服務(wù)請求和響應(yīng)組成。
傳輸層建立了主機端到端的鏈接,傳輸層的作用是為上層協(xié)議提供端到端的可靠和透明的數(shù)據(jù)傳輸服務(wù),包括處理差錯控制和流量控制等問題。該層向高層屏蔽了下層數(shù)據(jù)通信的細節(jié),使高層用戶看到的只是在兩個傳輸實體間的一條主機到主機的、可由用戶控制和設(shè)定的、可靠的數(shù)據(jù)通路。我們通常說的,TCP
UDP
就是在這一層。端口號既是這里的“端”。
本層通過 IP
尋址來建立兩個節(jié)點之間的連接,為源端的運輸層送來的分組,選擇合適的路由和交換節(jié)點,正確無誤地按照地址傳送給目的端的運輸層。就是通常說的 IP
層。這一層就是我們經(jīng)常說的 IP
協(xié)議層。IP
協(xié)議是 Internet
的基礎(chǔ)。我們可以這樣理解,網(wǎng)絡(luò)層規(guī)定了數(shù)據(jù)包的傳輸路線,而傳輸層則規(guī)定了數(shù)據(jù)包的傳輸方式。
將比特組合成字節(jié),再將字節(jié)組合成幀,使用鏈路層地址 (以太網(wǎng)使用MAC地址)來訪問介質(zhì),并進行差錯檢測。
網(wǎng)絡(luò)層與數(shù)據(jù)鏈路層的對比,通過上面的描述,我們或許可以這樣理解,網(wǎng)絡(luò)層是規(guī)劃了數(shù)據(jù)包的傳輸路線,而數(shù)據(jù)鏈路層就是傳輸路線。不過,在數(shù)據(jù)鏈路層上還增加了差錯控制的功能。
實際最終信號的傳輸是通過物理層實現(xiàn)的。通過物理介質(zhì)傳輸比特流。規(guī)定了電平、速度和電纜針腳。常用設(shè)備有(各種物理設(shè)備)集線器、中繼器、調(diào)制解調(diào)器、網(wǎng)線、雙絞線、同軸電纜。這些都是物理層的傳輸介質(zhì)。
OSI七層模型通信特點:對等通信
對等通信,為了使數(shù)據(jù)分組從源傳送到目的地,源端OSI模型的每一層都必須與目的端的對等層進行通信,這種通信方式稱為對等層通信。在每一層通信過程中,使用本層自己協(xié)議進行通信。
TCP/IP
五層協(xié)議和 OSI
的七層協(xié)議對應(yīng)關(guān)系如下:
從上圖中可以看出,TCP/IP
模型比 OSI
模型更加簡潔,它把 應(yīng)用層/表示層/會話層
全部整合為了 應(yīng)用層
。
在每一層都工作著不同的設(shè)備,比如我們常用的交換機就工作在數(shù)據(jù)鏈路層的,一般的路由器是工作在網(wǎng)絡(luò)層的。
在每一層實現(xiàn)的協(xié)議也各不同,即每一層的服務(wù)也不同,下圖列出了每層主要的傳輸協(xié)議:
同樣,TCP/IP
五層協(xié)議的通信方式也是對等通信:
TCP 和 UDP都是傳輸層協(xié)議,他們都屬于TCP/IP協(xié)議族:
(1)UDP
UDP的全稱是用戶數(shù)據(jù)報協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無連接的協(xié)議。在OSI模型中,在傳輸層,處于IP協(xié)議的上一層。UDP有不提供數(shù)據(jù)包分組、組裝和不能對數(shù)據(jù)包進行排序的缺點,也就是說,當(dāng)報文發(fā)送之后,是無法得知其是否安全完整到達的。
它的特點如下:
1)面向無連接
首先 UDP 是不需要和 TCP一樣在發(fā)送數(shù)據(jù)前進行三次握手建立連接的,想發(fā)數(shù)據(jù)就可以開始發(fā)送了。并且也只是數(shù)據(jù)報文的搬運工,不會對數(shù)據(jù)報文進行任何拆分和拼接操作。
具體來說就是:
2)有單播,多播,廣播的功能
UDP 不止支持一對一的傳輸方式,同樣支持一對多,多對多,多對一的方式,也就是說 UDP 提供了單播,多播,廣播的功能。
3)面向報文
發(fā)送方的UDP對應(yīng)用程序交下來的報文,在添加首部后就向下交付IP層。UDP對應(yīng)用層交下來的報文,既不合并,也不拆分,而是保留這些報文的邊界。因此,應(yīng)用程序必須選擇合適大小的報文
4)不可靠性
首先不可靠性體現(xiàn)在無連接上,通信都不需要建立連接,想發(fā)就發(fā),這樣的情況肯定不可靠。
并且收到什么數(shù)據(jù)就傳遞什么數(shù)據(jù),并且也不會備份數(shù)據(jù),發(fā)送數(shù)據(jù)也不會關(guān)心對方是否已經(jīng)正確接收到數(shù)據(jù)了。
再者網(wǎng)絡(luò)環(huán)境時好時壞,但是 UDP 因為沒有擁塞控制,一直會以恒定的速度發(fā)送數(shù)據(jù)。即使網(wǎng)絡(luò)條件不好,也不會對發(fā)送速率進行調(diào)整。這樣實現(xiàn)的弊端就是在網(wǎng)絡(luò)條件不好的情況下可能會導(dǎo)致丟包,但是優(yōu)點也很明顯,在某些實時性要求高的場景(比如電話會議)就需要使用 UDP 而不是 TCP。
5)頭部開銷小,傳輸數(shù)據(jù)報文時是很高效的。
UDP 頭部包含了以下幾個數(shù)據(jù):
因此 UDP 的頭部開銷小,只有8字節(jié),相比 TCP 的至少20字節(jié)要少得多,在傳輸數(shù)據(jù)報文時是很高效的。
(2)TCP
TCP的全稱是傳輸控制協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。TCP 是面向連接的、可靠的流協(xié)議(流就是指不間斷的數(shù)據(jù)結(jié)構(gòu))。
它有以下幾個特點:
1)面向連接
面向連接,是指發(fā)送數(shù)據(jù)之前必須在兩端建立連接。建立連接的方法是“三次握手”,這樣能建立可靠的連接。建立連接,是為數(shù)據(jù)的可靠傳輸打下了基礎(chǔ)。
2)僅支持單播傳輸
每條TCP傳輸連接只能有兩個端點,只能進行點對點的數(shù)據(jù)傳輸,不支持多播和廣播傳輸方式。
3)面向字節(jié)流
TCP不像UDP一樣那樣一個個報文獨立地傳輸,而是在不保留報文邊界的情況下以字節(jié)流方式進行傳輸。
4)可靠傳輸
對于可靠傳輸,判斷丟包、誤碼靠的是TCP的段編號以及確認號。TCP為了保證報文傳輸?shù)目煽?,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然后接收端實體對已成功收到的字節(jié)發(fā)回一個相應(yīng)的確認(ACK);如果發(fā)送端實體在合理的往返時延(RTT)內(nèi)未收到確認,那么對應(yīng)的數(shù)據(jù)(假設(shè)丟失了)將會被重傳。
5)提供擁塞控制
當(dāng)網(wǎng)絡(luò)出現(xiàn)擁塞的時候,TCP能夠減小向網(wǎng)絡(luò)注入數(shù)據(jù)的速率和數(shù)量,緩解擁塞。
6)提供全雙工通信
TCP允許通信雙方的應(yīng)用程序在任何時候都能發(fā)送數(shù)據(jù),因為TCP連接的兩端都設(shè)有緩存,用來臨時存放雙向通信的數(shù)據(jù)。當(dāng)然,TCP可以立即發(fā)送一個數(shù)據(jù)段,也可以緩存一段時間以便一次發(fā)送更多的數(shù)據(jù)段(最大的數(shù)據(jù)段大小取決于MSS)
UDP | TCP | |
---|---|---|
是否連接 | 無連接 | 面向連接 |
是否可靠 | 不可靠傳輸,不使用流量控制和擁塞控制 | 可靠傳輸(數(shù)據(jù)順序和正確性),使用流量控制和擁塞控制 |
連接對象個數(shù) | 支持一對一,一對多,多對一和多對多交互通信 | 只能是一對一通信 |
傳輸方式 | 面向報文 | 面向字節(jié)流 |
首部開銷 | 首部開銷小,僅8字節(jié) | 首部最小20字節(jié),最大60字節(jié) |
適用場景 | 適用于實時應(yīng)用,例如視頻會議、直播 | 適用于要求可靠傳輸?shù)膽?yīng)用,例如文件傳輸 |
UDP在傳輸數(shù)據(jù)之前不需要先建立連接,遠地主機的運輸層在接收到UDP報文后,不需要確認,提供不可靠交付??偨Y(jié)就以下四點:
由于TCP的下層網(wǎng)絡(luò)(網(wǎng)絡(luò)層)可能出現(xiàn)丟失、重復(fù)或失序的情況,TCP協(xié)議提供可靠數(shù)據(jù)傳輸服務(wù)。為保證數(shù)據(jù)傳輸?shù)恼_性,TCP會重傳其認為已丟失(包括報文中的比特錯誤)的包。TCP使用兩套獨立的機制來完成重傳,一是基于時間,二是基于確認信息。
TCP在發(fā)送一個數(shù)據(jù)之后,就開啟一個定時器,若是在這個時間內(nèi)沒有收到發(fā)送數(shù)據(jù)的ACK確認報文,則對該報文進行重傳,在達到一定次數(shù)還沒有成功時放棄并發(fā)送一個復(fù)位信號。
TCP的擁塞控制機制主要是以下四種機制:
(1)慢啟動(慢開始)
(2)擁塞避免
(3)快速重傳
(4)快速恢復(fù)
一般來說,流量控制就是為了讓發(fā)送方發(fā)送數(shù)據(jù)的速度不要太快,要讓接收方來得及接收。TCP采用大小可變的滑動窗口進行流量控制,窗口大小的單位是字節(jié)。這里說的窗口大小其實就是每次傳輸?shù)臄?shù)據(jù)大小。
TCP 的可靠傳輸機制是基于連續(xù) ARQ 協(xié)議和滑動窗口協(xié)議的。
TCP 協(xié)議在發(fā)送方維持了一個發(fā)送窗口,發(fā)送窗口以前的報文段是已經(jīng)發(fā)送并確認了的報文段,發(fā)送窗口中包含了已經(jīng)發(fā)送但 未確認的報文段和允許發(fā)送但還未發(fā)送的報文段,發(fā)送窗口以后的報文段是緩存中還不允許發(fā)送的報文段。當(dāng)發(fā)送方向接收方發(fā) 送報文時,會依次發(fā)送窗口內(nèi)的所有報文段,并且設(shè)置一個定時器,這個定時器可以理解為是最早發(fā)送但未收到確認的報文段。 如果在定時器的時間內(nèi)收到某一個報文段的確認回答,則滑動窗口,將窗口的首部向后滑動到確認報文段的后一個位置,此時如 果還有已發(fā)送但沒有確認的報文段,則重新設(shè)置定時器,如果沒有了則關(guān)閉定時器。如果定時器超時,則重新發(fā)送所有已經(jīng)發(fā)送 但還未收到確認的報文段,并將超時的間隔設(shè)置為以前的兩倍。當(dāng)發(fā)送方收到接收方的三個冗余的確認應(yīng)答后,這是一種指示, 說明該報文段以后的報文段很有可能發(fā)生丟失了,那么發(fā)送方會啟用快速重傳的機制,就是當(dāng)前定時器結(jié)束前,發(fā)送所有的已發(fā) 送但確認的報文段。
接收方使用的是累計確認的機制,對于所有按序到達的報文段,接收方返回一個報文段的肯定回答。如果收到了一個亂序的報文 段,那么接方會直接丟棄,并返回一個最近的按序到達的報文段的肯定回答。使用累計確認保證了返回的確認號之前的報文段都 已經(jīng)按序到達了,所以發(fā)送窗口可以移動到已確認報文段的后面。
發(fā)送窗口的大小是變化的,它是由接收窗口剩余大小和網(wǎng)絡(luò)中擁塞程度來決定的,TCP 就是通過控制發(fā)送窗口的長度來控制報文 段的發(fā)送速率。
但是 TCP 協(xié)議并不完全和滑動窗口協(xié)議相同,因為許多的 TCP 實現(xiàn)會將失序的報文段給緩存起來,并且發(fā)生重傳時,只會重 傳一個報文段,因此 TCP 協(xié)議的可靠傳輸機制更像是窗口滑動協(xié)議和選擇重傳協(xié)議的一個混合體。
三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務(wù)器總共發(fā)送3個包。進行三次握手的主要作用就是為了確認雙方的接收能力和發(fā)送能力是否正常、指定自己的初始化序列號為后面的可靠性傳送做準(zhǔn)備。實質(zhì)上其實就是連接服務(wù)器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號,交換TCP窗口大小信息。
剛開始客戶端處于 Closed 的狀態(tài),服務(wù)端處于 Listen 狀態(tài)。
首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數(shù)據(jù),但要消耗掉一個序號。
在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y
確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始為seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數(shù)據(jù),不攜帶數(shù)據(jù)則不消耗序號。
那為什么要三次握手呢?兩次不行嗎?
如客戶端發(fā)出連接請求,但因連接請求報文丟失而未收到確認,于是客戶端再重傳一次連接請求。后來收到了確認,建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接,客戶端共發(fā)出了兩個連接請求報文段,其中第一個丟失,第二個到達了服務(wù)端,但是第一個丟失的報文段只是在某些網(wǎng)絡(luò)結(jié)點長時間滯留了,延誤到連接釋放以后的某個時間才到達服務(wù)端,此時服務(wù)端誤認為客戶端又發(fā)出一次新的連接請求,于是就向客戶端發(fā)出確認報文段,同意建立連接,不采用三次握手,只要服務(wù)端發(fā)出確認,就建立新的連接了,此時客戶端忽略服務(wù)端發(fā)來的確認,也不發(fā)送數(shù)據(jù),則服務(wù)端一致等待客戶端發(fā)送數(shù)據(jù),浪費資源。
簡單來說就是以下三步:
TCP 三次握手的建立連接的過程就是相互確認初始序號的過程,告訴對方,什么樣序號的報文段能夠被正確接收。 第三次握手的作用是客戶端對服務(wù)器端的初始序號的確認。如果只使用兩次握手,那么服務(wù)器就沒有辦法知道自己的序號是否 已被確認。同時這樣也是為了防止失效的請求報文段被服務(wù)器接收,而出現(xiàn)錯誤的情況。
剛開始雙方都處于 ESTABLISHED 狀態(tài),假如是客戶端先發(fā)起關(guān)閉請求。四次揮手的過程如下:
即發(fā)出連接釋放報文段(FIN=1,序號seq=u),并停止再發(fā)送數(shù)據(jù),主動關(guān)閉TCP連接,進入FIN_WAIT1(終止等待1)狀態(tài),等待服務(wù)端的確認。
即服務(wù)端收到連接釋放報文段后即發(fā)出確認報文段(ACK=1,確認號ack=u+1,序號seq=v),服務(wù)端進入CLOSE_WAIT(關(guān)閉等待)狀態(tài),此時的TCP處于半關(guān)閉狀態(tài),客戶端到服務(wù)端的連接釋放??蛻舳耸盏椒?wù)端的確認后,進入FIN_WAIT2(終止等待2)狀態(tài),等待服務(wù)端發(fā)出的連接釋放報文段。
即服務(wù)端沒有要向客戶端發(fā)出的數(shù)據(jù),服務(wù)端發(fā)出連接釋放報文段(FIN=1,ACK=1,序號seq=w,確認號ack=u+1),服務(wù)端進入LAST_ACK(最后確認)狀態(tài),等待客戶端的確認。
即客戶端收到服務(wù)端的連接釋放報文段后,對此發(fā)出確認報文段(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME_WAIT(時間等待)狀態(tài)。此時TCP未釋放掉,需要經(jīng)過時間等待計時器設(shè)置的時間2MSL后,客戶端才進入CLOSED狀態(tài)。
那為什么需要四次揮手呢?
因為當(dāng)服務(wù)端收到客戶端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文。其中ACK報文是用來應(yīng)答的,SYN報文是用來同步的。但是關(guān)閉連接時,當(dāng)服務(wù)端收到FIN報文時,很可能并不會立即關(guān)閉SOCKET,所以只能先回復(fù)一個ACK報文,告訴客戶端,“你發(fā)的FIN報文我收到了”。只有等到我服務(wù)端所有的報文都發(fā)送完了,我才能發(fā)送FIN報文,因此不能一起發(fā)送,故需要四次揮手。
簡單來說就是以下四步:
TCP 使用四次揮手的原因是因為 TCP 的連接是全雙工的,所以需要雙方分別釋放到對方的連接,單獨一方的連接釋放,只代 表不能再向?qū)Ψ桨l(fā)送數(shù)據(jù),連接處于的是半釋放的狀態(tài)。
最后一次揮手中,客戶端會等待一段時間再關(guān)閉的原因,是為了防止發(fā)送給服務(wù)器的確認報文段丟失或者出錯,從而導(dǎo)致服務(wù)器 端不能正常關(guān)閉。
默認情況下, TCP 連接會啟?延遲傳送算法 (Nagle 算法), 在數(shù)據(jù)發(fā)送之前緩存他們. 如果短時間有多個數(shù)據(jù)發(fā)送, 會緩沖到?起作?次發(fā)送 (緩沖大小見 socket.bufferSize ), 這樣可以減少 IO 消耗提?性能.
如果是傳輸?件的話, 那么根本不?處理粘包的問題, 來?個包拼?個包就好了。但是如果是多條消息, 或者是別的?途的數(shù)據(jù)那么就需要處理粘包.
下面看?個例?, 連續(xù)調(diào)?兩次 send 分別發(fā)送兩段數(shù)據(jù) data1 和 data2, 在接收端有以下?種常?的情況:
A. 先接收到 data1, 然后接收到 data2 .
B. 先接收到 data1 的部分?jǐn)?shù)據(jù), 然后接收到 data1 余下的部分以及 data2 的全部.
C. 先接收到了 data1 的全部數(shù)據(jù)和 data2 的部分?jǐn)?shù)據(jù), 然后接收到了 data2 的余下的數(shù)據(jù).
D. ?次性接收到了 data1 和 data2 的全部數(shù)據(jù).
其中的 BCD 就是我們常?的粘包的情況. ?對于處理粘包的問題, 常?的解決?案有:
WebSocket是HTML5提供的一種瀏覽器與服務(wù)器進行全雙工通訊的網(wǎng)絡(luò)技術(shù),屬于應(yīng)用層協(xié)議。它基于TCP傳輸協(xié)議,并復(fù)用HTTP的握手通道。瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接, 并進行雙向數(shù)據(jù)傳輸。
WebSocket 的出現(xiàn)就解決了半雙工通信的弊端。它最大的特點是:服務(wù)器可以向客戶端主動推動消息,客戶端也可以主動向服務(wù)器推送消息。
WebSocket原理:客戶端向 WebSocket 服務(wù)器通知(notify)一個帶有所有接收者ID(recipients IDs)的事件(event),服務(wù)器接收后立即通知所有活躍的(active)客戶端,只有ID在接收者ID序列中的客戶端才會處理這個事件。
WebSocket 特點的如下:
Websocket的使用方法如下:
在客戶端中:
// 在index.html中直接寫WebSocket,設(shè)置服務(wù)端的端口號為 9999
let ws = new WebSocket('ws://localhost:9999');
// 在客戶端與服務(wù)端建立連接后觸發(fā)
ws.onopen = function() {
console.log("Connection open.");
ws.send('hello');
};
// 在服務(wù)端給客戶端發(fā)來消息的時候觸發(fā)
ws.onmessage = function(res) {
console.log(res); // 打印的是MessageEvent對象
console.log(res.data); // 打印的是收到的消息
};
// 在客戶端與服務(wù)端建立關(guān)閉后觸發(fā)
ws.onclose = function(evt) {
console.log("Connection closed.");
};
短輪詢和長輪詢的目的都是用于實現(xiàn)客戶端和服務(wù)器端的一個即時通訊。
短輪詢的基本思路:瀏覽器每隔一段時間向瀏覽器發(fā)送 http 請求,服務(wù)器端在收到請求后,不論是否有數(shù)據(jù)更新,都直接進行響應(yīng)。這種方式實現(xiàn)的即時通信,本質(zhì)上還是瀏覽器發(fā)送請求,服務(wù)器接受請求的一個過程,通過讓客戶端不斷的進行請求,使得客戶端能夠模擬實時地收到服務(wù)器端的數(shù)據(jù)的變化。這種方式的優(yōu)點是比較簡單,易于理解。缺點是這種方式由于需要不斷的建立 http 連接,嚴(yán)重浪費了服務(wù)器端和客戶端的資源。當(dāng)用戶增加時,服務(wù)器端的壓力就會變大,這是很不合理的。
長輪詢的基本思路:首先由客戶端向服務(wù)器發(fā)起請求,當(dāng)服務(wù)器收到客戶端發(fā)來的請求后,服務(wù)器端不會直接進行響應(yīng),而是先將這個請求掛起,然后判斷服務(wù)器端數(shù)據(jù)是否有更新。如果有更新,則進行響應(yīng),如果一直沒有數(shù)據(jù),則到達一定的時間限制才返回。客戶端 JavaScript 響應(yīng)處理函數(shù)會在處理完服務(wù)器返回的信息后,再次發(fā)出請求,重新建立連接。長輪詢和短輪詢比起來,它的優(yōu)點是明顯減少了很多不必要的 http 請求次數(shù),相比之下節(jié)約了資源。長輪詢的缺點在于,連接掛起也會導(dǎo)致資源的浪費。
SSE 的基本思想:服務(wù)器使用流信息向服務(wù)器推送信息。嚴(yán)格地說,http 協(xié)議無法做到服務(wù)器主動推送信息。但是,有一種變通方法,就是服務(wù)器向客戶端聲明,接下來要發(fā)送的是流信息。也就是說,發(fā)送的不是一次性的數(shù)據(jù)包,而是一個數(shù)據(jù)流,會連續(xù)不斷地發(fā)送過來。這時,客戶端不會關(guān)閉連接,會一直等著服務(wù)器發(fā)過來的新的數(shù)據(jù)流,視頻播放就是這樣的例子。SSE 就是利用這種機制,使用流信息向瀏覽器推送信息。它基于 http 協(xié)議,目前除了 IE/Edge,其他瀏覽器都支持。它相對于前面兩種方式來說,不需要建立過多的 http 請求,相比之下節(jié)約了資源。
WebSocket 是 HTML5 定義的一個新協(xié)議議,與傳統(tǒng)的 http 協(xié)議不同,該協(xié)議允許由服務(wù)器主動的向客戶端推送信息。使用 WebSocket 協(xié)議的缺點是在服務(wù)器端的配置比較復(fù)雜。WebSocket 是一個全雙工的協(xié)議,也就是通信雙方是平等的,可以相互發(fā)送消息,而 SSE 的方式是單向通信的,只能由服務(wù)器端向客戶端推送信息,如果客戶端需要發(fā)送信息就是屬于下一個 http 請求了。
上面的四個通信協(xié)議,前三個都是基于HTTP協(xié)議的。
對于這四種即使通信協(xié)議,從性能的角度來看:
WebSocket > 長連接(SEE) > 長輪詢 > 短輪詢
但是,我們?nèi)绻紤]瀏覽器的兼容性問題,順序就恰恰相反了:
短輪詢 > 長輪詢 > 長連接(SEE) > WebSocket
所以,還是要根據(jù)具體的使用場景來判斷使用哪種方式。
更多建議: