動(dòng)畫講解TCP,再不懂請來打我
前言
TCP 三次握手過程對于面試是必考的一個(gè),所以不但要掌握 TCP 整個(gè)握手的過程,其中有些小細(xì)節(jié)也更受到面試官的青睞。
對于這部分掌握以及 TCP 的四次揮手,小鹿將會(huì)以動(dòng)畫的形式呈現(xiàn)給每個(gè)人,這樣將復(fù)雜的知識(shí)簡單化,理解起來也容易了很多,尤其對于一個(gè)初學(xué)者來說。
思維導(dǎo)圖
TCP是什么
TCP(Transmission Control Protocol 傳輸控制協(xié)議)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。
我們知道了上述了解到了 TCP 的定義,通俗一點(diǎn)的講,TCP 就是一個(gè)雙方通信的一個(gè)規(guī)范標(biāo)準(zhǔn)(協(xié)議)。
我們在學(xué)習(xí) TCP 握手過程之前,首先必須了解 TCP 報(bào)文頭部的一些標(biāo)志信息,因?yàn)樵?TCP 握手的過程中,會(huì)使用到這些報(bào)文信息,如果沒有掌握這些信息,在學(xué)習(xí)握手過程中,整個(gè)人處于懵逼狀態(tài),也是為了能夠深入 TCP 三次握手的原理。
TCP頭部報(bào)文
1. source port 和 distination port
兩者分別為「源端口號(hào)」和「目的端口號(hào)」。
源端口號(hào)就是指本地端口,目的端口就是遠(yuǎn)程端口。
一個(gè)數(shù)據(jù)包(pocket)被解封裝成數(shù)據(jù)段(segment)后就會(huì)涉及到連接上層協(xié)議的端口問題。
可以這么理解,我們可以想象發(fā)送方很多的窗戶,接收方也有很多的窗戶,這些窗口都標(biāo)有不同的端口號(hào),源端口號(hào)和目的端口號(hào)就分別代表從哪個(gè)規(guī)定的串口發(fā)送到對方接收的窗口。不同的應(yīng)用程度都有著不同的端口,之前網(wǎng)絡(luò)分層的文章中有提到過。
擴(kuò)展:
應(yīng)用程序的端口號(hào)和應(yīng)用程序所在主機(jī)的 IP 地址統(tǒng)稱為 socket(套接字),IP:端口號(hào), 在互聯(lián)網(wǎng)上 socket 唯一標(biāo)識(shí)每一個(gè)應(yīng)用程序,源端口+源IP+目的端口+目的IP稱為”套接字對“,一對套接字就是一個(gè)連接,一個(gè)客戶端與服務(wù)器之間的連接。
2. Sequence Numbe
稱為「序列號(hào)」。用于 TCP 通信過程中某一傳輸方向上字節(jié)流的每個(gè)字節(jié)的編號(hào),為了確保數(shù)據(jù)通信的有序性,避免網(wǎng)絡(luò)中亂序的問題。接收端根據(jù)這個(gè)編號(hào)進(jìn)行確認(rèn),保證分割的數(shù)據(jù)段在原始數(shù)據(jù)包的位置。
再通俗一點(diǎn)的講,每個(gè)字段在傳送中用序列號(hào)來標(biāo)記自己位置的,而這個(gè)字段就是用來完成雙方傳輸中確保字段原始位置是按照傳輸順序的。(發(fā)送方是數(shù)據(jù)是怎樣一個(gè)順序,到了接受方也要確保是這個(gè)順序)
- PS:初始序列號(hào)由自己定,而后緒的序列號(hào)由對端的
- ACK 決定:SN_x = ACK_y (x 的序列號(hào) = y 發(fā)給 x 的 ACK),這里后邊會(huì)講到。
3. Acknowledgment Numbe
稱為「確認(rèn)序列號(hào)」。確認(rèn)序列號(hào)是接收確認(rèn)端所期望收到的下一序列號(hào)。確認(rèn)序號(hào)應(yīng)當(dāng)是上次已成功收到數(shù)據(jù)字節(jié)序號(hào)加1,只有當(dāng)標(biāo)志位中的 ACK 標(biāo)志為 1 時(shí)該確認(rèn)序列號(hào)的字段才有效。主要用來解決不丟包的問題。
若確認(rèn)號(hào)=N,則表明:到序號(hào)N-1為止的所有數(shù)據(jù)都已正確收到。
在這里,現(xiàn)在我們只需知道它的作用是什么,就是在數(shù)據(jù)傳輸?shù)臅r(shí)候是一段一段的,都是由序列號(hào)進(jìn)行標(biāo)識(shí)的,所以說,接收端每接收一段,之后就想要的下一段的序列號(hào)就稱為「確認(rèn)序列號(hào)」。
4. TCP Flag
TCP 首部中有 6 個(gè)標(biāo)志比特,它們中的多個(gè)可同時(shí)被設(shè)置為 1,主要是用于操控 TCP 的狀態(tài)機(jī)的,依次為URG,ACK,PSH,RST,SYN,F(xiàn)IN。
不要求初學(xué)者全部掌握,在這里只講三個(gè)重點(diǎn)的標(biāo)志:
(1) ACK
這個(gè)標(biāo)識(shí)可以理解為發(fā)送端發(fā)送數(shù)據(jù)到接收端,發(fā)送的時(shí)候 ACK 為 0,標(biāo)識(shí)接收端還未應(yīng)答,一旦接收端接收數(shù)據(jù)之后,就將 ACK 置為 1,發(fā)送端接收到之后,就知道了接收端已經(jīng)接收了數(shù)據(jù)。
此標(biāo)志表示「應(yīng)答域有效」,就是說前面所說的TCP應(yīng)答號(hào)將會(huì)包含在 TCP 數(shù)據(jù)包中;
有兩個(gè)取值:0 和 1,為 1 的時(shí)候表示應(yīng)答域有效,反之為 0;
(2) SYN
表示「同步序列號(hào)」,是 TCP 握手的發(fā)送的第一個(gè)數(shù)據(jù)包。
用來建立 TCP 的連接。SYN 標(biāo)志位和 ACK 標(biāo)志位搭配使用,當(dāng)連接請求的時(shí)候,SYN=1,ACK=0連接被響應(yīng)的時(shí)候,SYN=1,ACK=1;這個(gè)標(biāo)志的數(shù)據(jù)包經(jīng)常被用來進(jìn)行端口掃描。掃描者發(fā)送一個(gè)只有 SYN 的數(shù)據(jù)包,如果對方主機(jī)響應(yīng)了一個(gè)數(shù)據(jù)包回來 ,就表明這臺(tái)主機(jī)存在這個(gè)端口??聪旅鎰?dòng)畫:
(3) FIN
表示發(fā)送端已經(jīng)達(dá)到數(shù)據(jù)末尾,也就是說雙方的數(shù)據(jù)傳送完成,沒有數(shù)據(jù)可以傳送了,發(fā)送FIN標(biāo)志位的 TCP 數(shù)據(jù)包后,連接將被斷開。這個(gè)標(biāo)志的數(shù)據(jù)包也經(jīng)常被用于進(jìn)行端口掃描。
這個(gè)很好理解,就是說,發(fā)送端只剩最后的一段數(shù)據(jù)了,同時(shí)要告訴接收端后邊沒有數(shù)據(jù)可以接受了,所以用FIN標(biāo)識(shí)一下,接收端看到這個(gè)FIN之后,哦!這是接受的最后的數(shù)據(jù),接受完就關(guān)閉了。動(dòng)畫如下:
5. Window size
稱為滑動(dòng)窗口大小。所說的滑動(dòng)窗口,用來進(jìn)行流量控制。
為什么進(jìn)行TCP三次握手?
第一,為了確認(rèn)雙方的接收與發(fā)送能力是否正常。第二,指定自己的初始化序列號(hào),為后面的可靠傳送做準(zhǔn)備。第三,如果是 https 協(xié)議的話,三次握手這個(gè)過程,還會(huì)進(jìn)行數(shù)字證書的驗(yàn)證以及加密密鑰的生成到。
如果你了解 UDP 的話,TCP 的出現(xiàn)正式彌補(bǔ)了 UDP 不可靠傳輸?shù)娜秉c(diǎn)。但是 TCP 的誕生,也必然增加了連接的復(fù)雜性。
TCP三次握手過程?
TCP 三次握手的過程掌握最重要的兩點(diǎn)就是客戶端和服務(wù)端狀態(tài)的變化,另一個(gè)是三次握手過程標(biāo)志信息的變化,那么掌握 TCP 的三次握手就簡單多了。下面我們就以動(dòng)畫形式進(jìn)行拆解三次握手過程。
初始狀態(tài):客戶端處于closed 狀態(tài),服務(wù)器處于listen(監(jiān)聽) 狀態(tài)。
第一次握手:客戶端發(fā)送請求報(bào)文將SYN = j(1)初始化序列號(hào)發(fā)送給客戶端,發(fā)送完之后客戶端處于SYN_Send狀態(tài)。
第二次握手:服務(wù)端受到 SYN 請求報(bào)文之后,如果同意連接,會(huì)以自己的SYN(服務(wù)端) = K(0)和ack(1) = SYN(客戶端) + 1(ACK = 1)報(bào)文作為應(yīng)答,服務(wù)器為SYN_Receive狀態(tài)。
第三次握手:客戶端接收到服務(wù)端的SYN + ACK,然后發(fā)送ack = SYN(服務(wù)端) + 1(ACK = 1)確認(rèn)包作為應(yīng)答,客戶端轉(zhuǎn)為established狀態(tài)。
為什么不是一次、兩次握手?
防止了服務(wù)器端的一直等待而浪費(fèi)資源。
為了防止已失效的連接請求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯(cuò)誤。如果此時(shí)客戶端發(fā)送的延遲的握手信息服務(wù)器收到,然后服務(wù)器進(jìn)行響應(yīng),認(rèn)為客戶端要和它建立連接,此時(shí)客戶端并沒有這個(gè)意思,但 server 卻以為新的運(yùn)輸連接已經(jīng)建立,并一直等待 client 發(fā)來數(shù)據(jù)。這樣,server 的很多資源就白白浪費(fèi)掉了。