這是一個計算機網絡中一個很熱門,很基礎的問題,也是面試常考的一個題,若是你會那不稀奇,若是你不會,那就會涼涼。我這裏來對我學的東西作一個整理,看完時候對這裏的知識應該會很清晰。首先先來名詞解釋,若是遇到不清晰的名詞,記得反過頭來看。面試
TCP
:TCP
在計算機網絡模型的傳輸層,對應的是主機到主機的傳輸,爲應用間通訊提供能力。TCP
是一個雙工協議,數據任什麼時候候均可以雙向傳輸,這就意味着客戶端和服務端能夠平等地發送、接收信息。編程
連接:是傳輸層的概念,連接是一種傳輸數據的行爲,是網絡行爲狀態的記錄。在傳輸以前,創建一個連接,就是在數據收發雙方的內存中都創建一個用於維護數據傳輸狀態的對象,裏面記錄了雙方的IP
和端口號,狀態是怎樣,傳輸速度是如何等。後端
雙工/單工:服務器
名稱 | 概念 | 線路數量 |
---|---|---|
單工 | 在任何一個時刻,若是數據只能單向發送 | 只需1條( =1 ) |
半雙工 | 在某個時刻數據能夠向一個方向傳輸,也能夠向另外一個方向反方向傳輸,並且交替進行 | 至少 1 條( >= 1 ) |
全雙工 | 任什麼時候刻數據均可以雙向收發 | 大於 1 條( >1 ) |
TCP
的握手目的是爲了創建穩定的連接通道。TCP
的揮手目的是爲了斷開連接。WSL(Maximum Segment Lifetime)
:報文最大生存時間,TCP容許不一樣的實現能夠設置不一樣的WSL值。seq
序號:用來標識從TCP
源端向目的端發送的字節流,發起方發送數據時對此進行標記📌。ack
肯定序號:只有ACK
標誌爲1時,確認序號字段纔有效,ack = seq + 1
SYN(Synchronization)
:一個 Host
主動向另外一個 Host
發起鏈接,請求同步。ACK(Acknowledgement)
:由於要保持鏈接和可靠性約束,TCP
協議要保證每一條發出的數據必須給返回。接收方收到數據後,都須要給發送方一個響應確認序號有序。RST(Reset)
:重置連接FIN(Finish)
:一個Host
主動斷開請求,請求完成PSH(Push)
:一個 Host
給另外一個Host
發送數據,數據推送TCP
的三次握手,相對來講是一個比較完整的機制,旨在創建穩定的傳輸通道。markdown
下面來看一下TCP
創建連接的6個步驟:網絡
(SYN)
(SYN)
給一個(ACK)
(SYN)
給客戶端(ACK)
其中,2和5步驟是不須要進行握手的,3和4是能夠合併到一塊兒的。因此雖然創建連接要6步可是隻須要三次握手,分別是1,3+4,6。併發
下面咱們把三次握手的過程還原一下:app
CLOSED
的狀態,客戶端發送SYN=1
給服務端表示要求創建連接,而且發送了一個seq
序號,這個時候客戶端的狀態變成SYN-SEND
。ACK=1
表示確認收到,還有ack肯定序號,是上一個seq
序號+1
,即x+1
,還有本次的seq
序號y
,還有一個SYN=1
創建連接,這個時候服務端狀態變成SYN-REVD
。ACK=1
表示確認收到,還有一個新的seq
序號是x+1
,還有一個ack
肯定序號是上一個seq
序號+1
,即y+1
。完成以後客戶端的狀態編程ESTABLISHED
。ESTABLISHED
,連接通道創建。簡要總結就是:ui
設想一下,若是隻有兩次,服務端尚未肯定客戶端是否準備好了,這樣是沒法穩定的進行數據傳輸的。若是四次,服務端根據客戶端的ACK
再給客戶端回覆一個ACK
,沒有什麼很大的做用還形成資源浪費,那就是很沒有必要的事情了。三次正好既能夠保證可靠傳輸,也能夠提升傳輸效率,url
TCP
的揮手旨在把連接狀態斷開
(FIN)
。(ACK)
。 ACK
;也有可能服務端本身有資源要釋放等。(FIN)
。FIN
,處理本身完成的事情,好比客戶端有發送給服務端沒有收到 ACK
的請求等。(ACK)
。其中3和5是不須要進行揮手的,可是注意這裏,2和4是沒法合併的。因此這裏須要四次揮手,分別是1,2,4,6。
FIN=1
要斷開連接,而且發送了一個seq
序號=u
,這個時候客戶端變成FIN-WAIT1
。ACK=1
肯定消息,還有ack
確認序號,是上一個seq
序號+1
,即u+1
,還有一個新的seq
序號爲v
,此時服務端的狀態變成CLOSE-WAIT
,客戶端收到消息以後,狀態會變成FIN-WAIT2
。ACK=1
,還要發送ack
確認序號,上一個seq
序號+1
,即u+1
,還有一個新的seq
序號爲w
,還要發送一個FIN=1
。若是有以前沒有發送完的數據,會跟着此次請求一併發送給客戶端。此時服務端的狀態變成LASE-ACK
。ACK=1
確認消息,還發送了ack
確認序號,上一個seq
序號+1
,即w+1
,還有一個新的seq
序號爲u+1
,而後客戶端的狀態就變成了TIME-WAIT
,這種狀態會持續2WSL
,若是等待的這段時間再也不收到後端的消息,2WSL
以後會變成CLOSED
。服務端接收到消息以後,狀態也變成CLOSED
。簡要總結就是:
由於斷開連接服務端接收到FIN
時,斷開鏈接要處理的問題比較多,不能直接關閉連接,這個時候若是不發送ACK
迴應說是內容收到了,客戶端是沒法判斷這個消息服務端收到沒有,不能讓客戶端在這種狀況下等過久,因此應該先回復一個ACK
報文說是收到了,你等會我這裏還有事情要處理。等到服務端的事情都處理完畢了,再發送一個FIN
,肯定能夠斷開連接了。
ACK
報文能夠到達服務器,若是這個ACK
報文丟失,服務器會以爲客戶端沒有收到我發的請求斷開報文,因而服務器就會重發一次,若是客戶端在這個2MSL
時間段內收到重傳的報文,就會從新給出迴應報文,還會重啓2MSL
計時器。2WSL
時間中,可使本連接持續時間內產生的全部報文段從網絡中消失,這樣新的TCP
三次握手的時候就不會出現舊連接中失效的請求報文。TCP
在傳輸層,對應主機到主機的傳輸,爲應用通訊提供能力,且TCP
是一個雙工協議,爲了保證雙方都創建穩定而高效的數據傳輸,使用三次握手和四次揮手的工做機制。
三次握手的步驟是:
SYN
創建連接的請求 (大哥,能創建連接嗎?)
ACK+SYN
打包爲一條消息回覆 (老妹兒,我收到你的消息了,能夠進行連接,你收到了嗎?)
ACK
做爲回覆 (好嘞,走起~)
,這個時候數據傳輸通道創建。爲何不是兩次,是由於客戶端不返回ACK
,那麼服務端不知道客戶端有沒有接收到消息,若是是四次,根據ACK
再返回一次ACK
,浪費帶寬且沒有必要。
四次揮手的步驟是:
FIN
斷開連接的請求 (大哥,我這邊東西都發完了,斷開連接吧~)
ACK
進行回覆 (老妹兒?要斷開連接?我知道了,你稍等會兒啊)
FIN
給客戶端 (我這邊完事兒了,斷開連接吧~)
ACK
給服務端 (好嘞,掰掰~)
,這個時候數據傳輸通道斷開。爲何這裏是四次,是由於斷開連接服務端收到FIN
的時候,還有一些事情要處理,須要一些時間,這個時候不能讓客戶端等過久,因此先回復一個ACK
表示消息已經收到了,這邊有東西要處理稍微等一下。等到事情處理完,再給客戶端發送FIN贊成斷開連接。
其實這個很好理解,在生活中,咱們收到對方發送的一個文件或者一個視頻,這個時候他們須要咱們根據內容進行回覆或者點評。咱們應該先說一句內容收到了,我看看給你回覆,這樣不會讓對方有疑問半天沒有回覆是沒有收到仍是收到了正在看。等咱們看完以後再告訴對方他們要的結果。