TCP/IP協議
TCP/IP (Transmission Control Protocol/Internet Protocol),傳輸控制協議/網際協議,它是在網路使用中最基本的通信協議,TCP/IP協議不僅僅指的是TCP 和IP兩個協議,而是指一個由TCP、IP、HTTP、FTP等協議構成的協議簇, 只是因為在TCP/IP協議中TCP協議和IP協議最具代表性,所以被稱為TCP/IP協議,
TCP/IP傳輸協議是嚴格來說是一個四層的體系結構,應用層、傳輸層、網路層和資料鏈路層,協議只需關注本層問題,直接利用下層提供的服務,同時向上層提供服務,并且每層的更改不會影響其他層,當通過http發起一個請求時,應用層、傳輸層、網路層和鏈路層的相關協議依次對該請求進行包裝并攜帶對應的首部,最終在鏈路層生成以太網資料包,以太網資料包通過物理介質傳輸給對方主機,對方接收到資料包以后,然后再一層一層采用對應的協議進行拆包,最后把應用層資料交給應用程式處理,
- 應用層
最上層的,也是我們能直接接觸到的就是應用層(Application Layer),我們電腦或手機使用的應用軟體都是在應用層實作,應用層只需要專注于為用戶提供應用功能,不用去關心資料是如何傳輸的,就類似于,我們寄快遞的時候,只需要把包裹交給快遞員,由他負責運輸快遞,我們不需要關心快速是如何被運輸的,
- 傳輸層
當兩個不同設備的應用需要通信的時候,鏈路層定義了主機的身份,即MAC地址,而網路層定義了IP地址,明確了主機所在的網段,有了這兩個地址,資料包就從可以從一個主機發送到另一臺主機,但實際上資料包是從一個主機的某個應用程式發出,然后由對方主機的應用程式接收,而每臺電腦都有可能同時運行著很多個應用程式,所以當資料包被發送到主機上以后,是無法確定哪個應用程式要接收這個包,因此傳輸層引入了UDP協議來解決這個問題,為了給每個應用程式標識身份,
UDP協議
UDP協議定義了埠,同一個主機上的每個應用程式都需要指定唯一的埠號,并且規定網路中傳輸的資料包必須加上埠資訊,當資料包到達主機以后,就可以根據埠號找到對應的應用程式了,UDP協議比較簡單,實作容易,但它沒有確認機制,資料包一旦發出,無法知道對方是否收到,因此可靠性較差,為了解決這個問題,提高網路可靠性,TCP協議就誕生了,
TCP協議
TCP即傳輸控制協議,是一種面向連接的、可靠的通信協議,簡單來說TCP就是有確認機制的UDP協議,每發出一個資料包都要求確認,如果有一個資料包丟失,就收不到確認,發送方就必須重發這個資料包,為了保證傳輸的可靠性,TCP協議在UDP基礎之上建立了三次對話的確認機制,即在正式收發資料前,必須和對方建立可靠的連接,
傳輸層的主要作業是定義埠,標識應用程式身份,實作埠到埠的通信,TCP協議可以保證資料傳輸的可靠性,
TCP的三次握手
TCP的連接建立,常常稱為三次握手,“請求->應答->應答之應答”,為什么進行3次握手,主要防止已經失效的連接請求報文突然又傳送到了服務器,從而產生錯誤,
TCP四次揮手
假如在第二次揮手的時候,Server在給Client發送ACK的同時,也發送了FIN的請求,那么如果,Server還在接收從Client傳輸過來的資料,則會因為Client的下一個ACK而關閉接收資料的通道,資料就會接收失敗,
HTTP協議
- HTTP協議理解
HTTP是Hyper Text Transfer Protocol(超文本傳輸協議),是基于 TCP/IP 協議的應用層協議,理論上講,有了傳輸層,網路層,鏈路層這三層的支持,資料已經可以從一個主機上的應用程式傳輸到另一臺主機的應用程式了,但此時傳過來的資料是位元組流,不能很好的被程式識別,操作性差,因此,應用層定義了各種各樣的協議來規范資料格式,常見的有http,ftp等,在請求Header中,分別定義了請求資料格式Accept和回應資料格式Content-Type,有了這個規范以后,當對方接收到請求以后就知道該用什么格式來決議,然后對請求進行處理,最后按照請求方要求的格式將資料回傳,請求端接收到回應后,就按照規定的格式進行解讀,
從HTTP 1.1開始支持持久連接,也就是一次TCP連接可以發送多次的HTTP請求,
HTTP 的請求方法共計有 8 種,它們的描述如下所示:
- HTTP協議作業原理
在瀏覽器地址欄鍵入URL,按下回車之后會經歷以下流程:
1、瀏覽器向 DNS 服務器請求決議該 URL 中的域名所對應的 IP 地址;
2、決議出 IP 地址后,根據該 IP 地址和默認埠 80,和服務器建立TCP連接;
3、瀏覽器發出讀取檔案(URL 中域名后面部分對應的檔案)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的資料發送給服務器;
4、服務器對瀏覽器請求作出回應,并把對應的 html 文本發送給瀏覽器;
5、釋放 TCP連接;
6、瀏覽器將該 html 文本并顯示內容;
客戶與服務器之間的HTTP連接是一種一次性連接,它限制每次連接只處理一個請求,當服務器回傳本次請求的應答后便立即關閉連接,下次請求再重新建立連接,
HTTP協議采用了請求/回應模型,客戶端向服務器發送一個請求報文,請求報文包含請求的請求行、請求頭部和請求資料,服務器回應也是由三個部分組成,分別是:狀態行、訊息報頭、回應正文,
http請求由請求行,訊息報頭,請求正文三部分構成,
請求行由請求Method, URL 欄位和HTTP Version三部分構成, 總的來說請求行就是定義了本次請求的請求方式, 請求的地址, 以及所遵循的HTTP協議版本,
請求頭由一系列的鍵值對組成,允許客戶端向服務器端發送一些附加資訊或者客戶端自身的資訊,常用的請求報頭:
Host(發送請求時,該報頭域是必需的):
Host請求報頭域主要用于指定被請求資源的Internet主機和埠號,它通常從HTTP URL中提取出來的,eg:
我們在瀏覽器中輸入:http://www.guet.edu.cn/index.html,瀏覽器發送的請求訊息中,就會包含Host請求報頭域,如:Host:www.guet.edu.cn,此處使用預設埠號80,若指定了埠號,則變成:Host:www.guet.edu.cn:指定埠號,前后端分離專案中,則需要反向代理,
Connection:
Connection表示是否需要持久連接,即TCP連接默認不關閉,可以被多個請求復用,默認值“Keep-Alive”,(HTTP 1.1默認進行持久連接),但是http長連接不會一直保持,一般服務端都會設定keep-alive超時時間,超過指定的時間間隔,服務端就會主動關閉連接,同時服務端還會設定一個引數叫最大請求數,比如當最大請求數是300時,只要請求次數超過300次,即使還沒到超時時間,服務端也會主動關閉連接,不過,規范的做法是,客戶端在最后一個請求時,發送Connection: close,明確要求服務器關閉TCP連接,
Accept:
Accept請求報頭域代表發送端(客戶端)希望接受的資料型別,eg:Accept:image/gif,表明客戶端希望接受GIF圖象格式的資源;Accept:text/html,表明客戶端希望接受html文本,和服務器回傳的Content-Type相對應,常見型別:
- text/plain
- text/html
- text/css
- image/jpeg
- image/png
- image/svg+xml
- audio/mp4
- video/mp4
- application/javascript
- application/pdf
- application/zip
- application/atom+xml
Accept-Encoding
Accept-Encoding請求報頭域表示客戶端發送請求時告訴服務器,我可以解壓哪些格式的資料,相對應的content-encoding是指網頁使用了哪種壓縮方式傳輸資料給客戶端,eg:Accept-Encoding:gzip.deflate.如果請求訊息中沒有設定這個域,服務器假定客戶端對各種內容編碼都可以接受,
Accept-Language
Accept-Language請求報頭域類似于Accept,但是它是用于指定一種自然語言,eg:Accept-Language:zh-cn.如果請求訊息中沒有設定這個報頭域,服務器假定客戶端對各種語言都可以接受,
Authorization
Authorization請求報頭域主要用于證明客戶端有權查看某個資源,當瀏覽器訪問一個頁面時,如果收到服務器的回應代碼為401(未授權),可以發送一個包含Authorization請求報頭域的請求,要求服務器對其進行驗證,
cache-control 快取 是可以讓頁面加載速度變快的機制,
例:服務器可以通過在回復頭中設定response.setHeader(‘Cache-Control’, ‘max-age=30’) 數字是以秒為單位,帶有這些內容的頁面,這句話的意思就是這個頁面在接下來30秒的時間里如果有重復請求的操作時,不在請求而是直接從快取里讀取這個頁面檔案,
User-Agent
User-Agent請求報頭域允許客戶端將它的作業系統、瀏覽器和其它屬性告訴服務器,
服務器回應:狀態行、訊息報頭、回應正文,
狀態代碼有三位數字組成,第一個數字定義了回應的類別,且有五種可能取值:
1xx:指示資訊--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實作
5xx:服務器端錯誤--服務器未能實作合法的請求
HTTP/2
SPDY 協議
2009年,谷歌公開了自行研發的 SPDY 協議,主要解決 HTTP/1.1 效率不高的問題,這個協議在Chrome瀏覽器上證明可行以后,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承,
HTTP/2
2015年,HTTP/2 發布,它不叫 HTTP/2.0,是因為標準委員會不打算再發布子版本了,下一個新版本將是 HTTP/3,
當前主流的協議版本還是HTTP/1.1版本,
- 二進制協議
HTTP/1.1 版的頭資訊是文本(ASCII編碼),資料體可以是文本,也可以是二進制,HTTP/2 則是一個徹底的二進制協議,頭資訊和資料體都是二進制,并且統稱為"幀"(frame):頭資訊幀和資料幀,二進制決議方便很多,
- 多工
雖然1.1版允許復用TCP連接,但是同一個TCP連接里面,所有的資料通信是按次序進行的,服務端是按佇列順序處理請求的,服務器只有處理完一個回應,才會進行下一個回應,假如前面的請求處理時間很長,后面就會有許多請求排隊等著,這樣就造成了“隊頭阻塞”的問題,
HTTP/2 復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞",
舉例來說,在一個TCP連接里面,服務器同時收到了A請求和B請求,于是先回應A請求,結果發現處理程序非常耗時,于是就發送A請求已經處理好的部分, 接著回應B請求,完成后,再發送A請求剩下的部分,
這樣雙向的、實時的通信,就叫做多工(Multiplexing),
- 資料流
因為 HTTP/2 的資料包是不按順序發送的,同一個連接里面連續的資料包,可能屬于不同的回應,因此,必須要對資料包做標記,指出它屬于哪個回應,
HTTP/2 將每個請求或回應的所有資料包,稱為一個資料流(stream),每個資料流都有一個獨一無二的編號,資料包發送的時候,都必須標記資料流ID,用來區分它屬于哪個資料流,另外還規定,客戶端發出的資料流,ID一律為奇數,服務器發出的,ID為偶數,
資料流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個資料流,1.1版取消資料流的唯一方法,就是關閉TCP連接,這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用,客戶端還可以指定資料流的優先級,優先級越高,服務器就會越早回應,
- 頭資訊壓縮
HTTP 協議不帶有狀態,每次請求都必須附上所有資訊,所以,請求的很多欄位都是重復的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度,
HTTP/2 對這一點做了優化,引入了頭資訊壓碩訓制(header compression),一方面,頭資訊使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭資訊表,所有欄位都會存入這個表,生成一個索引號,以后就不發送同樣欄位了,只發送索引號,這樣就提高速度了,
- 服務器推送
HTTP/2 允許服務器未經請求,主動向客戶端發送資源,即服務器推送(server push),
- 提前將靜態資源推送到瀏覽器
- 推送可以基于已發送的請求,例如客戶端請求 html,服務端可以主動推送 js、css 檔案
當我們對支持HTTP2.0的web server請求資料的時候,服務器會順便把一些客戶端需要的資源一起推送到客戶端,免得客戶端再次創建連接發送請求到服務器端獲取,服務器端推送的這些資源其實存在客戶端的某處地方,客戶端直接從本地加載這些資源就可以了,不用走網路,速度自然是快很多的,
常見場景是客戶端請求一個網頁,這個網頁里面包含很多靜態資源,正常情況下,客戶端必須收到網頁后,決議HTML原始碼,發現有靜態資源,再發出靜態資源請求,其實,服務器可以預期到客戶端請求網頁后,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了,
服務端推送能把客戶端所需要的資源伴隨著index.html一起發送到客戶端,省去了客戶端重復請求的步驟,正因為沒有發起請求,建立連接等操作,所以靜態資源通過服務端推送的方式可以極大地提升速度,
GET和POST請求區別
TCP就像汽車,我們用TCP來運輸資料,它很可靠,從來不會發生丟件少件的現象,但是如果路上跑的全是看起來一模一樣的汽車,那這個世界看起來是一團混亂,送急件的汽車可能被前面滿載貨物的汽車攔堵在路上,整個交通系統一定會癱瘓,為了避免這種情況發生,交通規則HTTP誕生了,HTTP給汽車運輸設定了好幾個服務類別,有GET, POST, PUT, DELETE等等一共8類,HTTP規定,當執行GET請求的時候,要給汽車貼上GET的標簽(設定method為GET),而且要求把傳送的資料放在車頂上(url中)以方便記錄,如果是POST請求,就要在車上貼上POST的標簽,并把貨物放在車廂里,
還有另一個重要的角色:運輸公司,不同的瀏覽器(發起http請求)和服務器(接受http請求)就是不同的運輸公司, 雖然理論上,你可以在車頂上無限的堆貨物(url中無限加引數),但是運輸公司可不傻,裝貨和卸貨也是有很大成本的,他們會限制單次運輸量來控制風險,資料量太大對瀏覽器和服務器都是很大負擔,如果你用GET服務,在request body偷偷藏了資料,不同服務器的處理方式也是不同的,有些服務器會幫你卸貨,讀出資料,有些服務器直接忽略,所以,雖然GET可以帶request body,也不能保證一定能被接收到,
總結:HTTP只是個行為準則,HTTP的底層是TCP/IP,所以可以理解為GET和POST的底層也是TCP/IP,也就是說,GET/POST都是TCP鏈接,GET和POST能做的事情從本質上說是一樣的,
傳輸資料方式存在區別:
- 傳送方式:get通過地址欄傳輸,post通過報文傳輸(request body),
- get方式的安全性較Post方式要差些,包含機密資訊的話,建議用Post資料提交方式,在做資料查詢時,建議用Get方式;而在做資料添加、修改或洗掉時,建議用Post方式,
- 傳送長度:get有長度限制,一般限制在 2kb 左右;post傳送的資料量較大,一般被默認為不受限制, get和post的傳送資料大小跟各個瀏覽器、作業系統以及服務器的限制有關,
因為GET是通過URL提交資料,那么GET可提交的資料量就跟URL的長度有直接關系 了,而實際上,URL不存在引數上限的問題,HTTP協議規范沒有對URL長度進行限制,這個限制是特定的瀏覽器及服務器對它的限制,IE對URL長度的限制是2083位元組(2KB+35),用apache測驗,使用get方式,url最長可達8167b,
下面是幾種常見瀏覽器的url長度限制:(單位:位元組)
- IE : 2083
- Firefox:65536
- Chrome:8182
- Safari:80000
- Opera:190000
注意這是限制是整個URL長度,而不僅僅是你的引數值資料長度,請求的引數個數沒有限制,
POST是沒有大小限制的,HTTP協議規范也沒有進行大小限制,說“POST資料量存在 80K/100K的大小限制”是不準確的,POST資料是沒有限制的,起限制作用的是服務器的處理程式的處理能力,
- 請求快取:GET 會被快取,而post不會
- 保留瀏覽器歷史記錄:GET可以,而POST不能
- GET產生一個TCP資料包;POST產生兩個TCP資料包,
對于GET方式的請求,瀏覽器會把http header和data一并發送出去,服務器回應200(回傳資料),
get請求的程序:
(1)瀏覽器請求tcp連接(第一次握手)
(2)服務器答應進行tcp連接(第二次握手)
(3)瀏覽器確認,并發送get請求頭和資料(第三次握手,這個報文比較小,所以http會在此時進行第一次資料發送)
(4)服務器回傳200 OK回應
而對于POST,瀏覽器先發送header,服務器回應100 continue,瀏覽器再發送data,服務器回應200 ok(回傳資料),
post請求的程序:
(1)瀏覽器請求tcp連接(第一次握手)
(2)服務器答應進行tcp連接(第二次握手)
(3)瀏覽器確認,并發送post請求頭(第三次握手,這個報文比較小,所以http會在此時進行第一次資料發送)
(4)服務器回傳100 Continue回應
(5)瀏覽器發送資料
(6)服務器回傳200 OK回應
注意:
1. GET與POST都有自己的語意,不能隨便混用,
2. 在網路環境好的情況下,發一次包的時間和發兩次包的時間差別基本可以無視,而在網路環境差的情況下,兩次包的TCP在驗證資料包完整性上,有非常大的優點,
3. 并不是所有瀏覽器都會在POST中發送兩次包,Firefox就只發送一次,
7、POST 提交資料的幾種方式
Content-Type:服務端通常是根據請求頭(headers)中的 Content-Type 欄位來獲知請求中的訊息主體是用何種方式編碼,再對主體進行決議,
1). application/json 這種型別是我們現在最常用的,用來告訴服務端訊息主體是序列化后的 JSON 字串,
2). application/x-www-form-urlencoded ,form表單提交,上傳鍵值對,并且鍵值對都是間隔分開的,
3).multipart-form-data,是用來指定傳輸資料的特殊型別的,主要就是我們上傳的非文本的內容,比如圖片或者mp3等等,在使用包含檔案上傳控制元件的表單時,必須使用該值,
4).text/plain,純文本傳輸,在發送郵件時要設定這種編碼型別,否則會出現接收時編碼混亂的問題 ,
--
----
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/290409.html
標籤:其他
上一篇:在vue中使用websocket
下一篇:nginx服務器的下載安裝與使用
