簡析TCP的三次握手與四次分手
TCP是什麼?
具體的關於TCP是什麼,我不打算詳細的說了;當你看到這篇文章時,我想你也知道TCP的概念了,想要更深入的瞭解TCP的工作,我們就繼續。它只是一個超級麻煩的協議,而它又是網際網路的基礎,也是每個程式設計師必備的基本功。首先來看看OSI的七層模型:
我們需要知道TCP工作在網路OSI的七層模型中的第四層——Transport層,IP在第三層——Network層,ARP在第二層——Data Link層;在第二層上的資料,我們把它叫Frame,在第三層上的資料叫Packet,第四層的資料叫Segment。 同時,我們需要簡單的知道,資料從應用層發下來,會在每一層都會加上頭部資訊,進行封裝,然後再傳送到資料接收端。這個基本的流程你需要知道,就是每個資料都會經過資料的封裝和解封裝的過程。 在OSI七層模型中,每一層的作用和對應的協議如下:
TCP是一個協議,那這個協議是如何定義的,它的資料格式是什麼樣子的呢?要進行更深層次的剖析,就需要了解,甚至是熟記TCP協議中每個欄位的含義。哦,來吧。
上面就是TCP協議頭部的格式,由於它太重要了,是理解其它內容的基礎,下面就將每個欄位的資訊都詳細的說明一下。
- Source Port和Destination Port:分別佔用16位,表示源埠號和目的埠號;用於區別主機中的不同程式,而IP地址是用來區分不同的主機的,源埠號和目的埠號配合上IP首部中的源IP地址和目的IP地址就能唯一的確定一個TCP連線;
- Sequence Number:用來標識從TCP發端向TCP收端傳送的資料位元組流,它表示在這個報文段中的的第一個資料位元組在資料流中的序號;主要用來解決網路報亂序的問題;
- Acknowledgment Number:32位確認序列號包含傳送確認的一端所期望收到的下一個序號,因此,確認序號應當是上次已成功收到資料位元組序號加1。不過,只有當標誌位中的ACK標誌(下面介紹)為1時該確認序列號的欄位才有效。主要用來解決不丟包的問題;
- Offset:給出首部中32 bit字的數目,需要這個值是因為任選欄位的長度是可變的。這個欄位佔4bit(最多能表示15個32bit的的字,即4*15=60個位元組的首部長度),因此TCP最多有60位元組的首部。然而,沒有任選欄位,正常的長度是20位元組;
- TCP Flags:TCP首部中有6個標誌位元,它們中的多個可同時被設定為1,主要是用於操控TCP的狀態機的,依次為
URG
,ACK
,PSH
,RST
,SYN
,FIN
。每個標誌位的意思如下:- URG:此標誌表示TCP包的緊急指標域(後面馬上就要說到)有效,用來保證TCP連線不被中斷,並且督促中間層裝置要儘快處理這些資料;
- ACK:此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP資料包中;有兩個取值:0和1,為1的時候表示應答域有效,反之為0;
- PSH:這個標誌位表示Push操作。所謂Push操作就是指在資料包到達接收端以後,立即傳送給應用程式,而不是在緩衝區中排隊;
- RST:這個標誌表示連線復位請求。用來複位那些產生錯誤的連線,也被用來拒絕錯誤和非法的資料包;
- SYN:表示同步序號,用來建立連線。
SYN
標誌位和ACK
標誌位搭配使用,當連線請求的時候,SYN
=1,ACK
=0;連線被響應的時候,SYN
=1,ACK
=1;這個標誌的資料包經常被用來進行埠掃描。掃描者傳送一個只有SYN
的資料包,如果對方主機響應了一個資料包回來 ,就表明這臺主機存在這個埠;但是由於這種掃描方式只是進行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全的主機將會強制要求一個連線嚴格的進行TCP的三次握手; - FIN: 表示傳送端已經達到資料末尾,也就是說雙方的資料傳送完成,沒有資料可以傳送了,傳送
FIN
標誌位的TCP資料包後,連線將被斷開。這個標誌的資料包也經常被用於進行埠掃描。
- Window:視窗大小,也就是有名的滑動視窗,用來進行流量控制;這是一個複雜的問題,這篇博文中並不會進行總結的;
好了,基本知識都已經準備好了,開始下一段的征程吧。
三次握手又是什麼?
TCP是面向連線的,無論哪一方向另一方傳送資料之前,都必須先在雙方之間建立一條連線。在TCP/IP協議中,TCP協議提供可靠的連線服務,連線是通過三次握手進行初始化的。三次握手的目的是同步連線雙方的序列號和確認號並交換 TCP視窗大小資訊。這就是面試中經常會被問到的TCP三次握手。只是瞭解TCP三次握手的概念,對你獲得一份工作是沒有任何幫助的,你需要去了解TCP三次握手中的一些細節。先來看圖說話。
多麼清晰的一張圖,當然了,也不是我畫的,我也只是引用過來說明問題了。
- 第一次握手:建立連線。客戶端傳送連線請求報文段,將
SYN
位置為1,Sequence Number
為x;然後,客戶端進入SYN_SEND
狀態,等待伺服器的確認; - 第二次握手:伺服器收到
SYN
報文段。伺服器收到客戶端的SYN
報文段,需要對這個SYN
報文段進行確認,設定Acknowledgment Number
為x+1(Sequence Number
+1);同時,自己自己還要傳送SYN
請求資訊,將SYN
位置為1,Sequence Number
為y;伺服器端將上述所有資訊放到一個報文段(即SYN+ACK
報文段)中,一併傳送給客戶端,此時伺服器進入SYN_RECV
狀態; - 第三次握手:客戶端收到伺服器的
SYN+ACK
報文段。然後將Acknowledgment Number
設定為y+1,向伺服器傳送ACK
報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED
狀態,完成TCP三次握手。
完成了三次握手,客戶端和伺服器端就可以開始傳送資料。以上就是TCP三次握手的總體介紹。
那四次分手呢?
當客戶端和伺服器通過三次握手建立了TCP連線以後,當資料傳送完畢,肯定是要斷開TCP連線的啊。那對於TCP的斷開連線,這裡就有了神祕的“四次分手”。
- 第一次分手:主機1(可以使客戶端,也可以是伺服器端),設定
Sequence Number
和Acknowledgment Number
,向主機2傳送一個FIN
報文段;此時,主機1進入FIN_WAIT_1
狀態;這表示主機1沒有資料要傳送給主機2了; - 第二次分手:主機2收到了主機1傳送的
FIN
報文段,向主機1回一個ACK
報文段,Acknowledgment Number
為Sequence Number
加1;主機1進入FIN_WAIT_2
狀態;主機2告訴主機1,我也沒有資料要傳送了,可以進行關閉連線了; - 第三次分手:主機2向主機1傳送
FIN
報文段,請求關閉連線,同時主機2進入CLOSE_WAIT
狀態; - 第四次分手:主機1收到主機2傳送的
FIN
報文段,向主機2傳送ACK
報文段,然後主機1進入TIME_WAIT
狀態;主機2收到主機1的ACK
報文段以後,就關閉連線;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連線了。
至此,TCP的四次分手就這麼愉快的完成了。當你看到這裡,你的腦子裡會有很多的疑問,很多的不懂,感覺很凌亂;沒事,我們繼續總結。
為什麼要三次握手
既然總結了TCP的三次握手,那為什麼非要三次呢?怎麼覺得兩次就可以完成了。那TCP為什麼非要進行三次連線呢?在謝希仁的《計算機網路》中是這樣說的:
為了防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。
在書中同時舉了一個例子,如下:
“已失效的連線請求報文段”的產生在這樣一種情況下:client發出的第一個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的一個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用“三次握手”,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。”
這就很明白了,防止了伺服器端的一直等待而浪費資源。
為什麼要四次分手
那四次分手又是為何呢?TCP協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議。TCP是全雙工模式,這就意味著,當主機1發出FIN
報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部傳送完畢了;但是,這個時候主機1還是可以接受來自主機2的資料;當主機2返回ACK
報文段時,表示它已經知道主機1沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;當主機2也傳送了FIN
報文段時,這個時候就表示主機2也沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態變化。
FIN_WAIT_1
: 這個狀態要好好解釋一下,其實FIN_WAIT_1
和FIN_WAIT_2
狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1
狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連線,向對方傳送了FIN
報文,此時該SOCKET即進入到FIN_WAIT_1
狀態。而當對方回應ACK報文後,則進入到FIN_WAIT_2
狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1
狀態一般是比較難見到的,而FIN_WAIT_2
狀態還有時常常可以用netstat看到。(主動方)FIN_WAIT_2
:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2
狀態下的SOCKET,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ACK資訊),稍後再關閉連線。(主動方)CLOSE_WAIT
:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後傳送FIN
報文給自己,你係統毫無疑問地會回應一個ACK報文給對方,此時則進入到CLOSE_WAIT
狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個SOCKET,傳送FIN
報文給對方,也即關閉連線。所以你在CLOSE_WAIT
狀態下,需要完成的事情是等待你去關閉連線。(被動方)LAST_ACK
: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送FIN
報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)TIME_WAIT
: 表示收到了對方的FIN報文,併傳送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。如果FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT
狀態,而無須經過FIN_WAIT_2
狀態。(主動方)CLOSED
: 表示連線中斷。
我想你應該懂了
總結到這裡,也該結束了,但是對於TCP的學習遠還沒有結束。TCP是一個非常複雜的協議,這裡稍微總結了一下TCP的連線與斷開連線是發生的事情,其中還有很多的“坑”,讓我們後續有時間再繼續填吧。好了,完畢!
相關文章
- TCP的三次握手與四次分手TCP
- TCP三次握手四次分手TCP
- 圖解TCP三次握手與四次分手圖解TCP
- TCP戀愛史:三次握手和四次分手TCP
- TCP 的 三次握手 四次握手TCP
- TCP的三次握手與四次揮手TCP
- TCP 三次握手 與 四次揮手TCP
- TCP三次握手與四次揮手TCP
- 簡述TCP三次握手和四次揮手TCP
- TCP的三次握手四次揮手TCP
- TCP的三次握手與四次揮手詳解TCP
- TCP三次握手四次揮手TCP
- TCP三次握手&四次揮手TCP
- TCP 三次握手四次揮手TCP
- TCP:三次握手、四次握手、backlog及其他TCP
- 通俗易懂的TCP“三次握手”與“四次揮手”TCP
- TCP/IP的三次握手與四次揮手詳解TCP
- TCP三次握手和四次揮手TCP
- TCP 、 UDP、三次握手、四次揮手TCPUDP
- TCP-三次握手和四次揮手簡單理解TCP
- 探究 tcp 協議中的三次握手與四次揮手TCP協議
- TCP三次握手四次揮手介紹TCP
- TCP三次握手和四次揮手理解TCP
- TCP三次握手及四次揮手理解TCP
- 簡單說說TCP三次握手、四次揮手機制TCP
- 計算機網路-tcp的三次握手與四次揮手計算機網路TCP
- 說說TCP的三次握手和四次揮手TCP
- 圖解TCP的三次握手和四次揮手圖解TCP
- TCP協議的三次握手和四次揮手TCP協議
- 詳解TCP一:三次握手、四次揮手TCP
- tcp三次握手、四次揮手過程解析TCP
- TCP建立連線三次握手和釋放連線四次握手TCP
- TCP協議的三次握手與四次揮手過程圖解TCP協議圖解
- 看圖理解TCP的三次握手和四次揮手TCP
- Wireshark抓包分析TCP“三次握手,四次揮手”TCP
- TCP三次握手、四次揮手概念圖詳解TCP
- TCP 三次握手和四次揮手及其狀態TCP
- Wireshark捕獲理解TCP三次握手四次斷開TCP