這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1、導讀
記得上大學時上過《電腦網路基礎》專門課,當時真是單純善良無知,覺得我以後又不搞網路這一塊的東西,沒必要好好學習電腦網路這們課程,只要考試通過就行了。但是工作後的我發現,不管是我們是不是做軟體開發,都會多多少少接觸接觸到電腦網路,因為電腦網路無處不在。平時生活中我們要接觸到路由器,交換器,dns,ping,修改dns等等這些基本的操作,作為軟體開發人員,我們要接觸到tcp、udp、http、tcp串連三向交握,斷開四次揮手、socket等等這些專業點的知識,真是這些專業點的知識真是書到用時方恨少啊,接下來我們就好好複習吧。
OSI是Open System Interconnection的縮寫,意為開放式系統互聯。國際標準組織(ISO)制定了OSI模型,該模型定義了不同電腦互聯的標準,是設計和描述電腦網路通訊的基本架構。OSI模型把網路通訊的工作分為7層,分別是物理層、資料連結層、網路層、傳輸層、會話層、展示層和應用程式層。
記憶方法:記住前面的第一個字
物 數 網 傳 會 表 應
這七層每一層都有自己的作用,作用如分解:
這裡寫圖片描述
2、Http
HTTP(HyperText Transfer Protocol、超文字傳輸通訊協定 (HTTP))是OSI七層中應用程式層的協議。
協議解釋:
HTTP 是基於 TCP/IP協議的應用程式層協議。它不涉及資料包(packet)傳輸,主要規定了用戶端和伺服器之間的通訊格式,預設使用80連接埠。
有人說HTTP是一個基於TCP/IP通訊協定來傳遞資料(HTML 檔案, 圖片檔案, 查詢結果等),我覺這句話有問題,HTTP要是定義為協議那麼http只是一種規定規則,規定了用戶端的URI請求格式以及服務端資料響應格式,要說HTTP請求這個概念久比較籠統了,用戶端發送一次HTTP請求,經過OSI的七層協議的組裝、傳輸、拆分、傳輸等一些操作,最終可以獲得我們想要的資料。
用途描述:
解決用戶端和服務端的資料如何封裝,封裝兩端最後得到的資料可以被識別。
關係描述:
TPC/IP協議是傳輸層協議,主要解決資料 如何在網路中傳輸,而HTTP是應用程式層協議,主要解決如何封裝資料,而socket則是對TCP/IP協議的封裝和應用(程式員層面上)。實際上http協議就是建立在tcp/ip協議之上的。,幾乎每一種語言都有自己的Http實現,當然也有自己的Socket實現,比如Golang、Java,在自己的net包裡都可以找到原始碼。使用TCP協議是需要串連三向交握,中斷連線三次揮手的。
HTTP 是無狀態協議,它不對之前發生過的請求和響應的狀態進行管理。也就是說,無法根據之前的狀態進行本次的請求處理。但是使用Cookie和Session可以儲存狀態和識別。HTTP只能是由用戶端發起,服務端是無法主動想用戶端發送資料的。
2、TCP
TCP(Transmission Control Protocol,傳輸控制通訊協定)是OSI七層中傳輸層的協議。
協議解釋:
TCP(Transmission Control Protocol,傳輸控制通訊協定)是基於串連的協議,也就是說,在正式收發資料前,必須和對方建立可靠的串連。TCP提供逾時重發,丟棄重複資料,檢驗資料,流量控制等功能,保證資料能從一端傳到另一端。 理想狀態下,TCP串連一旦建立,在通訊雙方中的任何一方主動關閉串連前,TCP 串連都將被一直保持下去。中斷連線時伺服器和用戶端均可以主動發起斷開TCP串連的請求 。
安全體現在哪兒?
串連安全:三向交握 四次揮手,具體請參考:TCP詳解。
資料安全:TCP提供逾時重發,丟棄重複資料,檢驗資料,流量控制等功能,保證資料能從一端傳到另一端。
用途描述:
解決網路中的資料可以安全無錯的傳送
關係描述:
HTTP協議是基於TCP的,由於HTTP請求是一次請求一次應答,由於請求和應答都只有一次,所以就必須保證資料的安全性,在這一次的傳送中不好遺失資料,所以HTTP是要基於更加安全的TCP協議而不是UDP協議,Socket串連可以基於TCP也可以基於UDP,看具體的業務的需求了。HTTP請求使用基於TCP的Socket串連。
TCP發送的包有序號,對方收到包後要給一個反饋,如果超過一定時間還沒收到反饋就自動執行逾時重發,因此TCP最大的優點是可靠。一般網頁(http)、郵件(SMTP)、遠端連線(Telnet)、檔案(FTP)傳送就用TCP 。
TCP互動流程圖
3、UDP
UDP (User Datagram Protocol,使用者資料包通訊協定)是OSI參考模型中不需連線的傳輸層協議.
協議解釋:
UDP使用者資料包通訊協定,是一個不需連線的簡單的面向資料報的運輸層協議。UDP不提供可靠性,它只是把應用程式傳給IP層的資料報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸資料報前不用在客戶和伺服器之間建立一個串連,且沒有逾時重發等機制,故而傳輸速度很快。
用途描述:
解決網路中的資料可以高效的傳送
關係描述:
OSI參考模型中傳輸協議只有TCP和UDP兩種,TCP需要連結安全效率低,UDP無線串連不安全效率高,我們平時使用做多的HTTP協議基於TCP,很多語言都有HTTP請求的封裝,用起來很方便,但是想使用UDP就沒那麼方便了,想使用UDP我們就需要自己去寫一個Socket UDP了,Socket UDP不需要連結,用戶端知道服務端的IP和連接埠號碼直接發送資料就可以了,Socket TCP由於需要連結所以使用的時候需要心跳機制來確保連結沒有斷開。
UDP一般用於多點通訊和即時的資料業務,比如語音廣播、視頻、QQ、TFTP(簡單檔案傳送)、SNMP(簡易網路管理通訊協定)、RTP(即時傳送協議)RIP(路由資訊協議,如報告股票市場,航空資訊)、DNS(網域名稱解釋)。注重速度流暢。
UDP互動流程圖
4、Socket
名詞解釋:
socket是對TCP或者UDP協議的封裝和實現,socket並不是協議,差不多每一種語言都實現了對TCP和UDP封裝和實現的Socket程式碼程式庫,方便開發程式員使用。
用途描述:
socket是對TCP或者UDP協議的封裝和實現,這樣我就可以基於你所使用語言的Socket來實現更多的功能,有基於Socket TCP的HTTP請求,有基於Socket TCP長串連的訊息推送,也可以基於Socket TCP/UDP自訂一套自己的通訊協定。
關係描述:
HTTP基於TCP,HTTP請求需要使用Socket TCP來完成。
5、一次HTTP請求的心路曆程
由於一次HTTP請求會涉及到HTTP TCP Socket DNS 等等,弄清楚一次HTTP的流程大概可以知道網路請求的原理。那麼我們發送一次HTTP請求到底要經曆什嗎?
一次HTTP請求和響應要經曆的幾個步驟:
(1)網域名稱解析
網域名稱解析介意是用戶端的工作,用戶端只有服務端的網域名稱(類似www.baidu.com),並不知道服務端的IP地址,需要用戶端拿著網域名稱到DNS伺服器擷取網域名稱對應的IP地址。
(2) 建立TCP串連
由用戶端發起,在三向交握後用戶端和服務端建立TCP串連。所謂三向交握(Three-way Handshake),是指建立一個TCP串連時,需要用戶端和伺服器總共發送3個包。
三向交握的目的是串連伺服器指定連接埠,建立TCP串連,並同步串連雙方的序號和確認號並交換 TCP 視窗大小資訊.在 Socket 編程中,用戶端執行connect()時。將觸發三向交握。
TCP三向交握
首先瞭解一下幾個標誌,SYN(synchronous),同步標誌,ACK (Acknowledgement),即確認標誌,seq應該是Sequence Number,序號的意思,另外還有四次握手的fin,應該是final,表示結束標誌。
第一次握手:用戶端發送一個TCP的SYN標誌位置1的包指明客戶打算已連線的服務器的連接埠,以及初始序號X,儲存在包頭的序號(Sequence Number)欄位裡。
第二次握手:伺服器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均為1同時,將確認序號(Acknowledgement Number)設定為客戶的序號加1以,即X+1。
第三向交握:用戶端再次發送確認包(ACK) SYN標誌位為0,ACK標誌位為1。並且把伺服器發來ACK的序號欄位+1,放在確定欄位中發送給對方.並且在資料區段放寫序號的+1。
(3)發起http請求發送請求報文
由用戶端發起,用戶端組裝好請求報文,向服務端發送HTTP請求,HTTP由固定的格式,具體想看:
HTTP請求報文
HTTP請求報文由3部分組成(請求行+要求標頭+請求體),這三部分還有自己的組裝格式,這裡就不詳細說明了。
(4)伺服器端響應http請求
服務端收到用戶端的HTTP請求拿到請求報文後就響應請求,就是根據請求報文處理後發送資料到用戶端。服務端發送到用戶端的資料叫做響應報文,由服務端組裝,格式如下:
HTTP響應報文
① 報文協議及版本;
② 狀態代碼及狀態原因;
③ 響應報文頭,也是由多個屬性群組成;
④ 響應報文體,即我們真正要的“乾貨”。
(5)用戶端接收響應資料報文
在響應報文體裡面才是我們用戶端正真想要的東西,對於Android/IOS移動端來說一般都是Json資料,對於web瀏覽器來說一般都是HTML,用戶端獲得響應報文後就處理資料。
(6)關閉TCP串連
一般情況下TCP串連是由於用戶端主動關閉的,關閉需要用戶端主動發起四次揮手,才可以關閉TCP串連。一般情況下,一旦請求和響應完成了,就要關閉TCP串連,然後如果用戶端或者伺服器在其頭資訊加入了這行代碼:Connection:keep-alive,TCP串連在發送後將仍然保持開啟狀態,於是,用戶端可以繼續通過相同的串連發送請求。保持串連節省了為每個請求建立新串連所需的時間,還節約了網路頻寬。
TCP的串連的拆除需要發送四個包,因此稱為四次揮手(four-way handshake)。用戶端或伺服器均可主動發起揮手動作,在socket
編程中,任何一方執行close()操作即可產生揮手操作。
TCP斷開四次揮手
其實有個問題,為什麼串連的時候是三向交握,關閉的時候卻是四次揮手?
因為當Server端收到Client端的SYN串連請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來 同步的。但是關閉串連時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回複一個ACK報文,告訴Client端,” 你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。
舉例說明用戶端主動發送TCP關閉請求步驟:
第一次揮手:Client發送一個FIN,表示需要關閉Client到Server的資料傳送,Client進入FIN_WAIT_1狀態
第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號為收到序號+1,Server進入CLOSE_WAIT狀態
第三次揮手:Server發送一個FIN,用來關閉Server到Client的資料傳送,Server進入LAST_ACK狀態
第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手
最後圖解一次HTTP請求的心路曆程:
圖解一次HTTP請求的心路曆程
參考文章:
HTTP、TCP、UDP、Socket 知識總結
面試複習——Android工程師之網路基礎
Android網路請求心路曆程