三次握手
先上圖
報文標識解釋
SYN: synchronization (同步) - 占1位
ACK: acknowledgement (確認:告知已收到)
seq: 序列號, 當前端成功發(fā)送的數(shù)據(jù)位數(shù)
ack: 確認號, 為當前端成功接收的數(shù)據(jù)位數(shù)
seq和ack主要是為了記錄數(shù)據(jù)長度, 暫且按下不表
流程描述
client: [SYN] : 我準備發(fā)消息了
server: [SYN, ACK] : 好的, 我做好接收的準備了
client: [ACK] : 我知道了(然后開始發(fā)送消息)
疑問, 為什么這么設(shè)計?
- 理想情況下:
client: "我要開始了"
server: "好的"
然后client開始發(fā)送信息 - 第二種情況:
client: "我要開始了" -- 但是server沒有收到
client: 發(fā)現(xiàn)半天server都沒有反饋, 于是又發(fā)了一遍 "我要開始了"
server: "好的" -- 這回收到了
如果client發(fā)送的請求沒有被server收到, 那么長時間沒有收到server的回復后, 重新發(fā)送請求既可 - 第三種情況:
client: "我要開始了" -- 這個請求堵在路上了,server沒有收到
client: 重新發(fā)送 "我要開始了"
server: "好的"
client: "開始發(fā)送信息"
在發(fā)送信息的過程中,server收到了之前堵在路上的請求, 只能重新建立連接!!
這并不是我們希望的, 為了避免client本該失效的請求被server接收, 必須要多一次握手, 即三次握手
其它
在
HTTP/1.1中,keep-alive能夠復用TCP連接, 減少TCP三次握手的次數(shù), 從而提升性能
四次揮手
先上圖
報文標識解釋
FIN: finish (結(jié)束) - 占1位
流程描述
client: [FIN] : 消息已經(jīng)發(fā)送完畢了, 現(xiàn)在我要關(guān)閉連接了, 但仍保留接收消息的能力
server: [ACK] : 好的, 我知道了, 但是我還有一些數(shù)據(jù)包沒有發(fā)送, 弄完了, 我告訴你
server: [FIN, ACK] : 好了數(shù)據(jù)發(fā)送完了, 我先關(guān)為敬
client: [ACK] : OK 我也關(guān)了
疑問, 為什么這么設(shè)計?
和建立連接一樣的考慮, 需要3次揮手, 如下
client: "我要結(jié)束啦"
server: "好的"
client: "那我真的結(jié)束了"
但是結(jié)束和建立的一個區(qū)別在于,client想建立的時候,server能夠 隨時準備建立, 而client想結(jié)束的時候,server得先確保手中的數(shù)據(jù)發(fā)送完, 才能夠結(jié)束
所以中間的一次揮手要拆分為兩步, 如下:
client: "我要結(jié)束啦"
server: "好的, 等我把數(shù)據(jù)發(fā)完"
server: "我發(fā)完啦"
client: "那我真的結(jié)束啦" -- 如圖, 還有一個TIME-WAIT階段 (下面說)
然后client結(jié)束連接,server收到后也結(jié)束連接再考慮一種情況, 假如:
server沒有收到client發(fā)送的"那我真的結(jié)束啦"呢?超時重傳嗎?client都已經(jīng)關(guān)閉連接了!
所以解決辦法是:
client在發(fā)完 "那我真的結(jié)束啦" 后, 等待一段時間 (2MSL), 如果這段時間內(nèi)沒有收到server的重傳, 證明server已經(jīng)確實收到了
之后client可以放心的結(jié)束了, 這就是圖中TIME-WAIT階段的作用
MSL是Maximum Segment Lifetime, 譯為 "報文最大生存時間",
RFC 793中規(guī)定MSL為 2 分鐘, 實際應用中常用的是30s,1min,2min
ps: 我也不知道RFC 793是什么東東 = =!!
總結(jié)
3次握手,用來保障 通訊雙方 有通信的基礎(chǔ)
4次揮手,用來保障 通訊雙方 可以安全的回收 TCP通信的系統(tǒng)資源
參考
知乎 - 為什么http請求要3次握手與4次揮手?
CSDN - TCP的三次握手與四次揮手
CSDN - Time-wait狀態(tài)(2MSL)一些理解
CSDN - 理解TCP序列號和確認號
阿里 - hit-alibaba.github.io
掘金 - 精讀《圖解HTTP》