前言
上篇我們講了http愁拭,我們知道了http是基于tcp的,先來看張圖:
http是應(yīng)用層協(xié)議,tcp是傳輸層協(xié)議东帅,http作為上層協(xié)議建立在tcp之上。當(dāng)然你看到傳輸層協(xié)議還有一個(gè)兄弟叫udp球拦,這家伙經(jīng)常和tcp做比較冰啃,本篇不做講述,想知道的可自行了解吧刘莹,好了下面讓我們直接進(jìn)入正文吧阎毅。
tcp
傳輸控制協(xié)議(TCP,Transmission Control Protocol)是一種面向連接的点弯、可靠的扇调、基于字節(jié)流的傳輸層通信協(xié)議
傳輸就好比是我們買的快遞通過交通工具傳遞到我們手上,交通工具就是tcp抢肛,交到我們手上tcp就完成了它的任務(wù)了狼钮,剩下的就是http的事了碳柱,傳輸層協(xié)議就是干這個(gè)的。
tcp這個(gè)東西如果真要深究熬芜,恐怕一時(shí)半會(huì)也拎不清莲镣。所以我們根據(jù)tcp的兩大特點(diǎn):面向連接、可靠的來聊聊tcp吧涎拉。本篇我們先來講講tcp面向連接的這個(gè)特點(diǎn)吧瑞侮。
面向連接是什么?就是通訊雙方要先建立一條連接通道鼓拧。
說到面向連接半火,你想到了什么,對(duì)了季俩,就是那個(gè)钮糖?那個(gè)?
鼎鼎大名的tcp三次握手W米 店归!
每次面試面試官?zèng)]少問吧?就是下面這張圖:
讓我們形象化的說明三次握手吧酪我,三次握手的過程可以用打電話來模擬:
1消痛、客戶端說:服務(wù)器老哥你好,我是客戶端祭示,你能聽得到我嗎肄满?
2、服務(wù)器說:客戶端老弟你好质涛,我是服務(wù)器稠歉,我可以聽到你,請(qǐng)問你可以聽到我嗎汇陆?
3怒炸、客戶端說:服務(wù)器老哥,我可以聽到你毡代。
好了阅羹,建立連接了,讓我們開始聊天吧....
報(bào)文結(jié)構(gòu)
開始講三次握手先教寂,讓我們先來看個(gè)東西:tcp數(shù)據(jù)報(bào)文
TCP報(bào)文是TCP層傳輸?shù)臄?shù)據(jù)單元捏鱼,也叫報(bào)文段,可以看出一個(gè)完整的報(bào)文結(jié)構(gòu)由報(bào)頭和數(shù)據(jù)兩部分組成的酪耕。
源端口
源計(jì)算機(jī)上的應(yīng)用程序的端口號(hào)导梆,占16位。
目的端口
目標(biāo)計(jì)算機(jī)的應(yīng)用程序端口號(hào),占16位看尼。
seq(Sequence Number)
32位序列號(hào)递鹉,它表示該報(bào)文段發(fā)送數(shù)據(jù)的第一個(gè)字節(jié)的編號(hào),在 TCP 連接中藏斩,傳輸?shù)淖止?jié)流每一個(gè)字節(jié)都有個(gè)順序編號(hào)seq躏结,以此來保持傳輸?shù)挠行蛐浴I厦嬷蠸YN為1時(shí)狰域,表示用于同步初始序列號(hào)(ISN)媳拴。
ack(Acknowledgment Number)
32位確認(rèn)序列號(hào),它表示接收方期望收到發(fā)送方下一個(gè)報(bào)文段的第一個(gè)字節(jié)數(shù)據(jù)的編號(hào)北专。說白點(diǎn)就是接受方希望下一次發(fā)報(bào)文的時(shí)候發(fā)送方要發(fā)給我的序列號(hào)(seq)禀挫。
標(biāo)志位
標(biāo)志位指明該報(bào)文的行為旬陡,占用1位拓颓,本篇先講下面四個(gè)標(biāo)志位:
SYN
同步標(biāo)志位,當(dāng)SYN=1描孟,表示發(fā)起新的連接驶睦。
ACK
確認(rèn)標(biāo)志位,只有當(dāng) ACK=1時(shí)確認(rèn)號(hào)字段(ack)才有效匿醒。當(dāng) ACK=0 時(shí)场航,確認(rèn)號(hào)無效,TCP 規(guī)定廉羔,連接建立后溉痢,ACK 必須為 1。
PSH
推送標(biāo)志位憋他,告訴對(duì)方收到該報(bào)文段后是否立即把數(shù)據(jù)推送給上層孩饼。如果值為 1,表示應(yīng)當(dāng)立即把數(shù)據(jù)提交給上層竹挡,而不是緩存起來镀娶。
FIN
標(biāo)記數(shù)據(jù)是否發(fā)送完畢。如果 FIN=1揪罕,表示數(shù)據(jù)已經(jīng)發(fā)送完成梯码,可以釋放連接。
選項(xiàng):選項(xiàng)字段好啰,長(zhǎng)度可變轩娶,TCP 首部可以有多達(dá)40字節(jié)的可選信息,用于傳遞附加信息框往。
數(shù)據(jù):本次報(bào)文攜帶的數(shù)據(jù)字段鳄抒。
注明:窗口大小、TCP校驗(yàn)和、緊急指針字段不在本篇的討論范圍內(nèi)嘁酿。
狀態(tài)說明
CLOSED:表示初始關(guān)閉狀態(tài)
LISTEN:服務(wù)器監(jiān)聽狀態(tài)(等待客戶端的連接)
SYN_RECEIVED(SYN_RCVD):服務(wù)器接收到客戶端的SYN
SYN_SENT:客戶端已發(fā)送SYN
ESTABLISHED:表示連接已建立
上面了解了報(bào)文結(jié)構(gòu)和tcp連接過程幾種狀態(tài)隙券,再結(jié)合上面那張三次握手的圖片,我們?cè)賮碚降睦斫庀拢?/p>
三次握手過程
1闹司、第一次握手:客戶端發(fā)送SYN到服務(wù)器娱仔,表示要請(qǐng)求建立連接,開始進(jìn)入SYN_SENT狀態(tài)游桩。
2牲迫、第二次握手:服務(wù)器收到請(qǐng)求后,回復(fù)SYN + ACK到客戶端借卧,表示確認(rèn)了客戶端的請(qǐng)求盹憎,此時(shí)服務(wù)器進(jìn)入SYN_RCVD狀態(tài)。
3铐刘、第三次握手:客戶端收到SYN + ACK包陪每,向服務(wù)器發(fā)送確認(rèn)ACK包,客戶端進(jìn)入ESTABLISHED狀態(tài)镰吵,服務(wù)器收到請(qǐng)求后也進(jìn)入ESTABLISHED狀態(tài)檩禾,完成三次握手。
此時(shí) TCP 連接成功疤祭,客戶端與服務(wù)器開始傳送數(shù)據(jù)盼产。
說到這里。相信你也能和面試官扯皮了勺馆。你以為你說完了三次握手就行了戏售?what?你還是太年輕了草穆,這時(shí)候面試官肯定會(huì)來一句:為什么是三次握手灌灾?二次或者四次不行嘛?
為什么是三次握手续挟?
1.確定通信雙方是否具有可收發(fā)能力
嗯紧卒?如果是二次握手的話,你再看看上面那張三次握手圖诗祸,
第一次握手的時(shí)候跑芳,客戶端發(fā)送一個(gè)SYN包給服務(wù)器,第二次握手服務(wù)器回復(fù)了ACK+SYN給客戶端直颅,能收到服務(wù)器的確認(rèn)回復(fù)這說明了對(duì)于客戶端來說博个,客戶端能確認(rèn)了服務(wù)器的接收與發(fā)送的能力沒問題。
但是如果只是兩次握手的話功偿,那么問題來了盆佣,沒錯(cuò),客戶端是可以確認(rèn)服務(wù)器有收發(fā)的能力,可是服務(wù)器能確認(rèn)客戶端有這種能力嗎共耍?不能確認(rèn)了吧虑灰,因?yàn)闆]法得到客戶端的確認(rèn)回復(fù),服務(wù)器也不知道發(fā)沒發(fā)成功痹兜。
2.確定雙方初始序列號(hào)
其實(shí)你看圖就知道了穆咐,三次握手的過程其實(shí)就是在相互告知初始化序列號(hào)(ISN),并確定對(duì)方已經(jīng)收到的過程字旭。
如果只是兩次握手对湃,只有客戶端的起始序列號(hào)能被確認(rèn),服務(wù)器的序列號(hào)則得不到確認(rèn)遗淳。
呃拍柒。。屈暗。這個(gè)要怎么解釋呢拆讯?我們知道tcp為了保持有序,報(bào)文頭部需要依靠seq來保持有序恐锦,所以必須在建立連接時(shí)候雙方協(xié)定一個(gè)初始序列號(hào)往果,后續(xù)通信都是依賴這個(gè)初始序列號(hào)疆液,保證字節(jié)流上是有序的一铅。
如果無法保持有序,可能出現(xiàn)數(shù)據(jù)丟失堕油,或者亂序?qū)е聰?shù)據(jù)錯(cuò)誤等一系列問題潘飘,下面沒法玩了。
既然三次能到達(dá)目的掉缺,那為什么還要第四次呢卜录?浪費(fèi)資源不是?
最后說到底為什么需要三次握手眶明,因?yàn)閠cp要保持可靠啊艰毒,無論是確定雙方是否有接收發(fā)送的能力還是字節(jié)流傳輸保持有序都算是tcp可靠的一個(gè)體現(xiàn)了吧。
總結(jié)
本篇介紹了tcp并且基于tcp面向連接的特點(diǎn)講述了tcp的三次握手過程和三次握手的必要性搜囱,相信你也能和面試官扯皮了丑瞧,所以你學(xué)廢了么?下篇我們講講tcp的第二個(gè)特點(diǎn)可靠性吧蜀肘,敬請(qǐng)期待!
作者簡(jiǎn)介: 一個(gè)不像程序員的程序員绊汹,專注于前端開發(fā),偶爾也談?wù)剦?mèng)想扮宠。 公眾號(hào):前端程序之路