面試老是難免被問到 簡述 tcp 三次握手 四次揮手的問題。git
這個問題困擾我許久,由於我一直不能解釋清楚爲何 握手須要三次 揮手須要四次 爲何不是五次或者兩次 多一次少一次不行嗎?github
tcp 協議是用於兩臺機器在網絡上通信用的。面試
那麼這涉及到一個問題:怎麼保證在數據傳輸以前兩臺機器都有通信能力
。服務器
兩個對象
接收
和發送
消息以上的的條件須要 A 和 B 都知道雙方都擁有這個能力。(達成共識)網絡
我剛纔提到機器通信前須要雙方都在線而且都擁有通信能力
,那麼咱們看下最少須要多少步可以知足對話的必要條件。tcp
第一步:code
A 向 B 在必定時間範圍內發送[1]
嘗試想要創建連接的消息 (若是成功證實 A 可以發消息)cdn
第二步: (B 接受到 A 的消息)對象
B 向 A 發送[2]
收到了 A 的消息的消息 (已經證實 A 可以發送消息 B 可以接收消息) (未知的是 A 能不能收到 B 的消息,以及 B 能不能成功的發消息)blog
第三步: (A 接受到 B 的消息)
中止第一步的行爲。
此時 A 已經知道了 AB 都具備收發消息的能力。
可是 B 還不知道 A 能不能接收到消息。
因此這個時候須要 A 發送[3]
一條消息告訴 B 。
若是 B 收到了消息說明雙方都具有的完成一次對話的基本條件,tcp連接創建完成。
四次揮手的目的是爲了達到完成一次通信後可以關閉無用連接釋放掉服務器資源來作其餘的事。
因爲 tcp 是一種全雙工通信協議。
因此達到目的的標誌是
AB 雙方都關閉了本身的 接受數據
的接口 和 發送數據
的接口。
咱們來看下最少須要多少步:
一、A(主動方)發起[1]
斷開連接的請求告訴A全部數據發送完畢能夠關閉接收數據的接口 (只是說明A將要關閉發送接口,此時A正常接收數據)
二、B(被動方)接收到請求關閉接收數據的接口
向 A 發送[2]
確認關閉接收數據的接口的消息,叫A不要再次發送關閉連接的請求了。
A 收到 B 的確認消息後關閉了發送接口,等待 B 將全部的數據傳輸完畢後關閉接口的消息。
三、B 若是沒有數據傳輸給 A 了會發送[3]
一條關閉發送接口的消息給 A 讓 A 關閉本身的就收數據的接口。
四、A 收到 B 的消息後會關閉本身的接收數據接口,而且發送[4]
一條確認消息告訴 B 不要再次發送關閉接口的通知了。
如圖:
爲何創建鏈接是三次握手,而關閉鏈接倒是四次揮手呢?這是由於服務端在LISTEN狀態下,收到創建鏈接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。而關閉鏈接時,當收到對方的FIN報文時,僅僅表示對方再也不發送數據了可是還能接收數據,己方也未必所有數據都發送給對方了,因此己方能夠當即close,也能夠發送一些數據給對方後,再發送FIN報文給對方來表示贊成如今關閉鏈接,所以,己方ACK和FIN通常都會分開發送。
(完)