前言
如果你學(xué)過網(wǎng)絡(luò)基礎(chǔ)知識(shí),那么你一定對TCP三次握手不陌生。今天我想用通俗的話來給大家講一講TCP三次握手和四次揮手。畢竟,這個(gè)知識(shí)點(diǎn)在面試時(shí)被問到的概率很高!
TCP特點(diǎn)
① 面向連接
TCP是面向客戶端和服務(wù)器端連接的通訊協(xié)議,使用它可以將客戶端和服務(wù)器端進(jìn)行連接。數(shù)據(jù)通信之前,必須要有一個(gè)連接通道建立。
② 可靠性
是指無論網(wǎng)絡(luò)環(huán)境多差,TCP都可以保證信息一定能夠傳遞到接收端。TCP之所以可以保證可靠性主要得益于兩個(gè)方面,一個(gè)是“狀態(tài)性”,另一個(gè)是“可控制性”。所謂狀態(tài)性是指TCP會(huì)記錄信息的發(fā)送狀態(tài),例如,哪些數(shù)據(jù)收到了、哪些數(shù)據(jù)沒收到等狀態(tài)信息都會(huì)被記錄;可控制性是指TCP會(huì)根據(jù)狀態(tài)情況控制自己的行為,比如當(dāng)TCP意識(shí)到丟包了就會(huì)控制重發(fā)此包,這樣就實(shí)現(xiàn)了TCP的可靠性。 總之,TCP可以很好地處理傳輸過程中數(shù)據(jù)包丟失的情況,它會(huì)重復(fù)發(fā)送包,這個(gè)特性很關(guān)鍵。
③ 傳輸單位為數(shù)據(jù)段
是指TCP在數(shù)據(jù)傳輸時(shí),傳送的每一個(gè)數(shù)據(jù)包里的數(shù)據(jù)只是一個(gè)數(shù)據(jù)段單元,并非完整數(shù)據(jù),比如,要傳送一個(gè)1MB的文件,整個(gè)文件會(huì)被切割成諸多數(shù)據(jù)段,然后再進(jìn)行傳輸。 由于數(shù)據(jù)段大小受應(yīng)用層傳送給的報(bào)文大小和所途徑網(wǎng)絡(luò)中的MYU值大小決定,所以每次發(fā)送的TCP數(shù)據(jù)段大小是不固定的。在一個(gè)具體的網(wǎng)絡(luò)中,有一個(gè)MSS(Maximum Segment Size,即最大數(shù)據(jù)段大?。?,最小的和數(shù)據(jù)段可能僅有21字節(jié)(其中20字節(jié)屬于TCP數(shù)據(jù)段頭部,數(shù)據(jù)部分僅1字節(jié))。
④基于字節(jié)流
說到字節(jié)流,不得不提一下UDP的傳輸,UDP傳輸是基于報(bào)文的,簡單點(diǎn)理解,UDP傳輸一個(gè)消息,需要將整個(gè)消息封裝成一個(gè)數(shù)據(jù)包,然后進(jìn)行傳輸。而TCP不一樣,它會(huì)把整個(gè)消息切割成若干段,然后每一個(gè)段再被封裝成數(shù)據(jù)包,逐一傳輸??傊?,TCP不像UDP那樣以一個(gè)個(gè)報(bào)文獨(dú)立地進(jìn)行傳輸,而是在不保留報(bào)文邊界的情況下以字節(jié)流方式進(jìn)行傳輸。
TCP三次握手過程
了解了TCP的特點(diǎn)后,再來看TCP三次握手就容易理解為何要三次,而不是兩次啦。
一開始客戶端和服務(wù)端都是CLOSED狀態(tài),就好比他們兩個(gè)彼此相互不認(rèn)識(shí),誰都不理誰。下面為了更好理解三次握手,我把客戶端叫做小客,服務(wù)器叫做小服。
有一天小客需要小服幫忙,于是小客首先跟小服打招呼:你好小服,我需要你幫助,可以幫我嗎?(客戶端發(fā)送SYN=1,seq=x,這個(gè)x是一個(gè)隨機(jī)數(shù)) 小服收到消息后,會(huì)回一個(gè)反饋給到小客:你好小客,我可以幫助你啊,那我要如何幫你呢?(服務(wù)端發(fā)送SYN=1,ACK=1,同時(shí)發(fā)送seq=y,ack=x+1,這里的ack為客戶端發(fā)送的seq數(shù)值加1) 小客收到小服的反饋后,很高興,于是又跟小服回了一句:謝謝你小服,我需要你幫我做......(客戶端再次跟服務(wù)端發(fā)送ACK=1,seq=x+1,ack=y+1)。 小服再次收到小客的反饋后,小服就開始幫小服做事情了,從此成為了好基友!
做一個(gè)簡單總結(jié):
第一次握手:客戶端發(fā)送 SYN 報(bào)文,并進(jìn)入 SYN_SENT 狀態(tài),等待服務(wù)器的確認(rèn);
第二次握手:服務(wù)器收到 SYN 報(bào)文,需要給客戶端發(fā)送 ACK 確認(rèn)報(bào)文,同時(shí)服務(wù)器也要向客戶端發(fā)送一個(gè) SYN 報(bào)文,所以也就是向客戶端發(fā)送 SYN + ACK 報(bào)文,此時(shí)服務(wù)器進(jìn)入 SYN_RCVD 狀態(tài);
第三次握手:客戶端收到 SYN + ACK 報(bào)文,向服務(wù)器發(fā)送確認(rèn)包,客戶端進(jìn)入 ESTABLISHED 狀態(tài)。待服務(wù)器收到客戶端發(fā)送的 ACK 包也會(huì)進(jìn)入 ESTABLISHED 狀態(tài),完成三次握手。
TCP四次揮手
當(dāng)客戶端和服務(wù)端通信完畢后,需要斷開連接,釋放資源。在正式斷開連接之前,客戶端和服務(wù)端會(huì)出現(xiàn)幾個(gè)狀態(tài),先看四次揮手狀態(tài)圖:
我們還拿剛才小客和小服來舉例,小客的事情在小服的幫助下得到了圓滿結(jié)束,小客對小服非常感激,這一天小客跟小服提出了感謝。
小客:你好小服,我的事情在你的幫助下終于完成了,感謝你的幫忙,后面暫時(shí)不需要你的幫助啦。(FIN=1 seq=u)
小服:收到,小客,不用客氣啦。這陣我也太累了,是該休息一下啦,那我們就后會(huì)有期吧?(ACK=1 seq=v ack=u+1; FIN=1 seq=w ack=u+1)
小客:再次感謝,后會(huì)有期!(ACK=1 seq=u+1 ack=w+1)
之后小客和小服就沒有再聯(lián)系了。
再來做個(gè)總結(jié)吧:
客戶端發(fā)送斷開TCP連接請求的報(bào)文,其中報(bào)文中包含seq序列號(hào),是由發(fā)送端隨機(jī)生成的,并且還將報(bào)文中的FIN字段置為1,表示需要斷開TCP連接。(FIN=1,seq=x,x由客戶端隨機(jī)生成);
服務(wù)端會(huì)回復(fù)客戶端發(fā)送的TCP斷開請求報(bào)文,其包含seq序列號(hào),是由回復(fù)端隨機(jī)生成的,而且會(huì)產(chǎn)生ACK字段,ACK字段數(shù)值是在客戶端發(fā)過來的seq序列號(hào)基礎(chǔ)上加1進(jìn)行回復(fù),以便客戶端收到信息時(shí),知曉自己的TCP斷開請求已經(jīng)得到驗(yàn)證。(FIN=1,ACK=x+1,seq=y,y由服務(wù)端隨機(jī)生成);
服務(wù)端在回復(fù)完客戶端的TCP斷開請求后,不會(huì)馬上進(jìn)行TCP連接的斷開,服務(wù)端會(huì)先確保斷開前,所有傳輸?shù)紸的數(shù)據(jù)是否已經(jīng)傳輸完畢,一旦確認(rèn)傳輸數(shù)據(jù)完畢,就會(huì)將回復(fù)報(bào)文的FIN字段置1,并且產(chǎn)生隨機(jī)seq序列號(hào)。(FIN=1,ACK=x+1,seq=z,z由服務(wù)端隨機(jī)生成);
客戶端收到服務(wù)端的TCP斷開請求后,會(huì)回復(fù)服務(wù)端的斷開請求,包含隨機(jī)生成的seq字段和ACK字段,ACK字段會(huì)在服務(wù)端的TCP斷開請求的seq基礎(chǔ)上加1,從而完成服務(wù)端請求的驗(yàn)證回復(fù)。(FIN=1,ACK=z+1,seq=h,h為客戶端隨機(jī)生成)
TCP連接中的狀態(tài)說明
TCP三次握手和四次揮手過程中,客戶端和服務(wù)端出現(xiàn)了多個(gè)TCP連接狀態(tài),下面我來做一個(gè)列舉。
LISTEN:服務(wù)端上起了服務(wù)就會(huì)監(jiān)聽一個(gè)端口(例如SSHD服務(wù)監(jiān)聽22端口),等待客戶端來連接它。
SYN_SENT:客戶端想要連接服務(wù)端,先打招呼,也就是三次握手時(shí)的第一次,它把請求發(fā)出去后,就變成了這個(gè)狀態(tài),表示等待服務(wù)端的確認(rèn)。
SYN_RECEIVED:服務(wù)端接收到了客戶端的請求,之后需要反饋給客戶端確認(rèn)信息,并且同時(shí)也要把自己的請求信息一起發(fā)給客戶端,此時(shí)就會(huì)變成SYN_RECEIVED狀態(tài)。
ESTABLISHED:經(jīng)過三次握手后,客戶端和服務(wù)端相繼變成ESTABLISHED狀態(tài),表示雙方建立了連接。只有雙方都是該狀態(tài),才可以順利傳輸數(shù)據(jù)。
FIN_WAIT_1:客戶端和服務(wù)端傳輸完數(shù)據(jù)后,總有一方需要主動(dòng)發(fā)起關(guān)閉連接,這個(gè)FIN_WAIT_1狀態(tài)出現(xiàn)在主動(dòng)關(guān)閉方。當(dāng)它發(fā)起關(guān)閉連接的請求后,就會(huì)變成此狀態(tài)。它需要等待對方的確認(rèn)。
FIN_WAIT_2:主動(dòng)關(guān)閉方收到被動(dòng)關(guān)閉方的確認(rèn)信息后,就會(huì)變成此狀態(tài)。
CLOSE_WAIT:被動(dòng)關(guān)閉方收到主動(dòng)方的關(guān)閉請求后,會(huì)發(fā)出確認(rèn)信息,確認(rèn)信息發(fā)出后就出現(xiàn)了CLOSE_WAIT。
LAST_ACK:被動(dòng)關(guān)閉方除了發(fā)送確認(rèn)信息外,還需要發(fā)送關(guān)閉確認(rèn)信息給對方,這個(gè)信息發(fā)送完畢后,就會(huì)成為LAST_ACK狀態(tài),此時(shí)被動(dòng)關(guān)閉方只需要等待主動(dòng)關(guān)閉方的一個(gè)回饋確認(rèn)信息。
TIME_WAIT:主動(dòng)關(guān)閉方將最后一次的確認(rèn)信息發(fā)送給被動(dòng)關(guān)閉方,就會(huì)處于TIME_WAIT狀態(tài),該狀態(tài)只出現(xiàn)在主動(dòng)關(guān)閉方,它只需等待一個(gè)時(shí)間就會(huì)徹底關(guān)閉,這個(gè)等待的時(shí)間為2*MSL(Maximum Segment Lifetime,報(bào)文最長存活時(shí)間)。因?yàn)樗枰粋€(gè)等待時(shí)間,所以在Linux系統(tǒng)里,這個(gè)狀態(tài)是最常見、最多的狀態(tài)。
CLOSING:幾乎看不到的狀態(tài),表示正在關(guān)閉連接,這個(gè)是瞬時(shí)完成的。
CLOSED:徹底關(guān)閉連接的狀態(tài)(這是為方便描述假想的狀態(tài),實(shí)際不存在)
審核編輯:劉清
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
9123瀏覽量
85324 -
TCP
+關(guān)注
關(guān)注
8文章
1353瀏覽量
79055 -
ACK
+關(guān)注
關(guān)注
0文章
28瀏覽量
11144 -
UDP
+關(guān)注
關(guān)注
0文章
325瀏覽量
33931
原文標(biāo)題:再談TCP三次握手和四次揮手
文章出處:【微信號(hào):aming_linux,微信公眾號(hào):阿銘linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論