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