TCP連接的三次握手
了解TCP協(xié)議的人都知道共虑,TCP在建立連接的時(shí)候需要經(jīng)過三次交互己沛,俗稱「三次握手」:
- client端發(fā)送一個(gè)SYN段指明client打算連接的server端口癞蚕,以及初始序號(ISN)
- server發(fā)回包含server的初始化序號的SYN報(bào)文段作為應(yīng)答,同時(shí)將確認(rèn)序號(ACK)設(shè)置為client的ISN加1以對client的SYN報(bào)文段進(jìn)行確認(rèn)
- client必須將確認(rèn)序號(ACK)設(shè)置為server的ISN加1以對server的SYN報(bào)文段進(jìn)行確認(rèn)
完成這三次交互后狭园,client與server端就可以建立起一個(gè)TCP連接蓬蝶,雙方也可以通過該連接通道進(jìn)行數(shù)據(jù)的交互尘分,但是很多人也會有疑問,為什么一定要經(jīng)過三次交互才能建立連接呢丸氛?這三次是必須的嗎培愁?如果是那是為什么呢?下面缓窜,我將來解答這個(gè)問題
一定需要三次握手嗎定续?
要回答這個(gè)問題,我們首先想想TCP連接的目的禾锤,我想大家都知道私股,它的目的就是建立一個(gè)數(shù)據(jù)傳輸?shù)耐ǖ溃话憬⒁粋€(gè)通道需要哪些步驟呢恩掷?這里我們不妨舉一個(gè)現(xiàn)實(shí)中的例子:建立客運(yùn)線倡鲸;我們都知道,在建立客運(yùn)線之前黄娘,客運(yùn)線的起始站和終點(diǎn)站需要溝通峭状,只有雙方都同意了建立這條線(TCP連接的建立)并協(xié)調(diào)相關(guān)的車位等資源(啟用socket端口),才能有后續(xù)的汽車在這條線上運(yùn)行(TCP數(shù)據(jù)傳輸)逼争,首先來看正常的路線是如何建立的(假設(shè)需要在A优床,B兩個(gè)站之間建立客運(yùn)線):
- A站:B站你好,我想和你建立客運(yùn)線誓焦,請問你那邊能為我騰一個(gè)車位出來嗎羔巢?
- B站:好的!
- B站:A站你好,你那邊返程的車位準(zhǔn)備好了嗎竿秆?
- A站:返程的車位準(zhǔn)備好了启摄!
可以看到這里其實(shí)有四個(gè)階段,但是由于第2和第3階段都是由B站發(fā)往A站的信息幽钢,所以可以合并起來歉备,流程簡化如下:
- A站:B站你好,我想和你建立客運(yùn)線匪燕,請問你那邊能為我騰一個(gè)車位出來嗎蕾羊?
- B站:好的,另外帽驯,你那邊返程的車位準(zhǔn)備好了嗎龟再?
- A站:返程的車位準(zhǔn)備好了!
你看尼变,2利凑,3階段合并后的流程是不是就是TCP連接的三次握手!嫌术,但既然我們的問題是「一定需要三次握手嗎哀澈?」,所以我們可以進(jìn)一步思考度气,既然2割按,3階段可以合并,那么1磷籍,4階段能不能合并呢适荣?我們來看:
- A站:B站你好,我想和你建立客運(yùn)線院领,請問你那邊能為我騰一個(gè)車位出來嗎弛矛?另外,我這邊已經(jīng)為你騰出了返程的車位
- B站:好的栅盲,車位就緒汪诉!
你瞧,客運(yùn)線照樣可以建立谈秫,沒有任何問題扒寄,那么TCP的設(shè)計(jì)者為什么就一定要設(shè)計(jì)一個(gè)三次交互的方案呢?是他們的方案設(shè)計(jì)不夠簡潔嗎拟烫?肯定不是该编,作為因特網(wǎng)的底層支撐,設(shè)計(jì)者們不會容許這么一個(gè)冗余的方案存在的硕淑。
我們不妨再深入思考课竣,這里通過建立客運(yùn)線的場景模擬網(wǎng)絡(luò)連接的建立時(shí)忽略了一個(gè)點(diǎn)嘉赎,那就是網(wǎng)絡(luò)報(bào)文在傳輸?shù)臅r(shí)候可能會延遲或丟失,而上面兩階段交互的方案并沒有考慮信息丟失的情況于樟,現(xiàn)在我們假定A站和B站在進(jìn)行交互的時(shí)候用的是飛鴿傳書公条,雙方溝通時(shí)默認(rèn)一定時(shí)間內(nèi)未收到回信即認(rèn)為鴿子迷路了,就需要重發(fā)(模擬報(bào)文延時(shí)或丟失后的重發(fā)機(jī)制)迂曲,那么在這種情況下靶橱,兩階段交互是否能正常工作呢?
- A站:B站你好路捧,我想和你建立客運(yùn)線关霸,請問你那邊能為我騰一個(gè)車位出來嗎?另外杰扫,我這邊已經(jīng)為你騰出了返程的車位
- A站(未能及時(shí)收到回信队寇,重發(fā)):B站你好,我想和你建立客運(yùn)線章姓,請問你那邊能為我騰一個(gè)車位出來嗎佳遣?另外,我這邊已經(jīng)為你騰出了返程的車位
- B站(響應(yīng)重發(fā)的消息):好的啤覆,車位就緒苍日!
- 運(yùn)行一段時(shí)間后惭聂,客運(yùn)線關(guān)閉(假設(shè)是臨時(shí)路線)
- 第一階段丟失的那個(gè)信鴿此時(shí)將消息送到了窗声,即:(B站你好,我想和你建立客運(yùn)線辜纲,請問你那邊能為我騰一個(gè)車位出來嗎笨觅?另外,我這邊已經(jīng)為你騰出了返程的車位)
- B站:好的耕腾,車位就緒<!(這是一條死客運(yùn)線,不會有車過來)
我們發(fā)現(xiàn)扫俺,在兩階段交互方案中苍苞,由于信鴿的延時(shí)送達(dá),導(dǎo)致后續(xù)建立了一條本不該建立的連接狼纬,B站將不會迎來A站的汽車羹呵,而我們再看三階段交互的方案:
- A站:B站你好,我想和你建立客運(yùn)線疗琉,請問你那邊能為我騰一個(gè)車位出來嗎冈欢?
- A站(未能及時(shí)收到回信,重發(fā)):B站你好盈简,我想和你建立客運(yùn)線凑耻,請問你那邊能為我騰一個(gè)車位出來嗎太示?
- B站(響應(yīng)重發(fā)的消息):好的,另外香浩,你那邊返程的車位準(zhǔn)備好了嗎类缤?
- A站:返程的車位準(zhǔn)備好了!
- 運(yùn)行一段時(shí)間后邻吭,客運(yùn)線關(guān)閉(假設(shè)是臨時(shí)路線)
- 第一階段丟失的那個(gè)信鴿此時(shí)將消息送到了呀非,即:(B站你好,我想和你建立客運(yùn)線镜盯,請問你那邊能為我騰一個(gè)車位出來嗎岸裙?)
- B站:好的,另外速缆,你那邊返程的車位準(zhǔn)備好了嗎降允?
- 由于此時(shí)A站并不想建立到B站的線,所以忽略該信息
- B站沒有收到A站的回應(yīng)艺糜,所以也不會完成客運(yùn)線的建立
可以發(fā)現(xiàn)剧董,三階段交互可以解決這種由于信息延時(shí)或丟失導(dǎo)致的非真實(shí)意愿的連接的建立,對應(yīng)到TCP的三次握手破停,其實(shí)就是為了應(yīng)對已經(jīng)失效的連接請求報(bào)文突然又傳到服務(wù)端而產(chǎn)生的錯(cuò)誤場景翅楼,或者從另外一個(gè)角度看,如果網(wǎng)絡(luò)傳輸質(zhì)量一直處于理想狀態(tài)的話(不存在延時(shí)或丟失)真慢,兩次握手其實(shí)完全可以滿足連接建立的需求毅臊,而三次握手是一種能應(yīng)對網(wǎng)絡(luò)不穩(wěn)定情況的最簡方案