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