TCP/IP協議之三次握手、四次斷開詳解

TCP三次握手詳細介紹

1.TCP/IP協議簡單介紹:

TCP/IP是一個協議族,通常分不同層次進行工作,每個層次負責不同的通信功能。包含以下四個層次:

應用層:(http、telnet、Email、dns等協議)

傳輸層:(tcp和udp)

網絡層:(ip、icmp、rarp、bootp)

鏈路層:(設備驅動程序及接口卡)

1).鏈路層,也稱作數據鏈路層或者網絡接口層,通常包括操作系統中的設備驅動程序和計算機中對應的網絡接口卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理接口細節。

2).網絡層,也稱作互聯網層,處理分組在網絡中的活動,例如分組的選路。網絡層協議包括IP協議(網際協議)、ICMP協議(Internet互聯網控制報文協議),以及IGMP協議(Internet組管理協議)。

3).傳輸層主要是爲兩臺主機上的應用程序提供端到端的通信。在TCP/IP協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(用戶數據報協議)。TCP爲兩臺主機提供高可靠性的數據通信。他所作的工作包括把應用程序交給它的數據分成合適的小塊交給下面的網絡層,確認接收到的分組,設置發送最後確認分組的超時時間等。由於傳輸層提供了高可靠性的端到端通信,因此應用層可以忽略所有這些細節。而另一方面,UDP則爲應用層提供一種非常簡單的服務。它只是把稱作數據報的分組從一臺主機發送到另一臺主機,但並不保證該數據報能到達另一端。任何必須的可靠性必須由應用層來提供。

4).應用層負責處理特定的應用程序細節。包括Telnet(遠程登錄)、FTP(文件傳輸協議)、SMTP(簡單郵件傳送協議)以及SNMP(簡單網絡管理協議)等。

二. TCP協議

 TCP是一種面向連接(連接導向)的、可靠的基於字節流的傳輸層通信協議。TCP將用戶數據打包成報文段,它發送後啓動一個定時器,另一端收到的數據進行確認、對失序的數據重新排序、丟棄重複數據。

 TCP的特點有:
  1. TCP是面向連接的運輸層協議

  2. 每一條TCP連接只能有兩個端點,每一條TCP連接只能是點對點的

  3. TCP提供可靠交付的服務

  4. TCP提供全雙工通信。數據在兩個方向上獨立的進行傳輸。因此,連接的每一端必須保持每個方向上的傳輸數據序號。

  5. 面向字節流。面向字節流的含義:雖然應用程序和TCP交互是一次一個數據塊,但TCP把應用程序交下來的數據僅僅是一連串的無結構的字節流

TCP報文首部,如下圖所示:

源端口、目標端口:計算機上的進程要和其他進程通信是要通過計算機端口的,而一個計算機端口某個時刻只能被一個進程佔用,所以通過指定源端口和目標端口,就可以知道是哪兩個進程需要通信。源端口、目標端口是用16位表示的,可推算計算機的端口個數爲2^16個。

序列號:表示本報文段所發送數據的第一個字節的編號。在TCP連接中所傳送的字節流的每一個字節都會按順序編號。由於序列號由32位表示,所以每2^32個字節,就會出現序列號迴繞,再次從 0 開始。那如何區分兩個相同序列號的不同TCP報文段就是一個問題了,後面會有答案,暫時可以不管。

確認號:表示接收方期望收到發送方下一個報文段的第一個字節數據的編號。也就是告訴發送發:我希望你(指發送方)下次發送的數據的第一個字節數據的編號是這個確認號。也就是告訴發送方:我希望你(指發送方)下次發送給我的TCP報文段的序列號字段的值是這個確認號。

TCP首部長度:由於TCP首部包含一個長度可變的選項部分,所以需要這麼一個值來指定這個TCP報文段到底有多長。或者可以這麼理解:就是表示TCP報文段中數據部分在整個TCP報文段中的位置。該字段的單位是32位字,即:4個字節。

URG:表示本報文段中發送的數據是否包含緊急數據。URG=1,表示有緊急數據。後面的緊急指針字段只有當URG=1時纔有效。

ACK:表示是否前面的確認號字段是否有效。ACK=1,表示有效。只有當ACK=1時,前面的確認號字段纔有效。TCP規定,連接建立後,ACK必須爲1。

PSH:告訴對方收到該報文段後是否應該立即把數據推送給上層。如果爲1,則表示對方應當立即把數據提交給上層,而不是緩存起來。

RST:只有當RST=1時纔有用。如果你收到一個RST=1的報文,說明你與主機的連接出現了嚴重錯誤(如主機崩潰),必須釋放連接,然後再重新建立連接。或者說明你上次發送給主機的數據有問題,主機拒絕響應。

SYN:在建立連接時使用,用來同步序號。當SYN=1,ACK=0時,表示這是一個請求建立連接的報文段;當SYN=1,ACK=1時,表示對方同意建立連接。SYN=1,說明這是一個請求建立連接或同意建立連接的報文。只有在前兩次握手中SYN才置爲1。

FIN:標記數據是否發送完畢。如果FIN=1,就相當於告訴對方:“我的數據已經發送完畢,你可以釋放連接了”

窗口大小:表示現在運行對方發送的數據量。也就是告訴對方,從本報文段的確認號開始允許對方發送的數據量。

校驗和:提供額外的可靠性。具體如何校驗,參考其他資料。

緊急指針:標記緊急數據在數據字段中的位置。

選項部分:其最大長度可根據TCP首部長度進行推算。TCP首部長度用4位表示,那麼選項部分最長爲:(2^4-1)*4-20=40字節。

TCP三次握手過程

第一次握手:建立連接時,客戶端發送同步序號syn=1,隨機產生seq number數據包發送(seq=x)到服務器,並進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

第二次握手:服務器收到報文請求,由SYN=1知道客戶端要建立連接請求,向客戶端發送ack number(ack=x+1),syn=1,同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時服務器進入SYN_RCVD

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ack(ack=y+1),同時發送序號seq=y+1,此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。

TCP三次握手過程如下圖所示:
TCP/IP協議之三次握手、四次斷開詳解

四次斷開:

由於TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接。收到一個 FIN只意味着這一方向上沒有數據流動,一個TCP連接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

(1)客戶端A發送一個FIN,用來關閉客戶A到服務器B的數據傳送。

(2)服務器B收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1。和SYN一樣,一個FIN將佔用一個序號。

(3)服務器B關閉與客戶端A的連接,發送一個FIN給客戶端A。

(4)客戶端A發回ACK報文確認,並將確認序號設置爲收到序號加1。

TCP採用四次揮手關閉連接如圖所示。
TCP/IP協議之三次握手、四次斷開詳解

三次握手狀態詳細說明:

1.CLOSED:起始點,在超時或者連接關閉時候進入此狀態。

2.LISTEN:服務端在等待連接過來時候的狀態,服務端爲此要調用socket,bind,listen函數,就能進入此狀態。此稱爲應用程序被動打開(等待客戶端來連接)。

3.SYN_SENT:客戶端發起連接,發送SYN給服務器端。如果服務器端不能連接,則直接進入CLOSED狀態。

4.SYN_RCVD:跟3對應,服務器端接受客戶端的SYN請求,服務器端由LISTEN狀態進入SYN_RCVD狀態。同時服務器端要回應一個ACK,同時發送一個SYN給客戶端;另外一種情況,客戶端在發起SYN的同時接收到服務器端得SYN請求,客戶端就會由SYN_SENT到SYN_RCVD狀態。

5.ESTABLISHED:服務器端和客戶端在完成3次握手進入狀態,說明已經可以開始傳輸數據了。

四次斷開狀態詳細說明:

6.FIN_WAIT_1: 關閉的一方,由ESTABLISHED進入此狀態。具體的動作是發送FIN給對方。

7.FIN_WAIT_2: 閉的一方,接收到對方的FIN_ACK(即fin包的迴應包,進入此狀態。

8.CLOSE_WAIT: 接收到FIN以後,被動關閉的一方進入此狀態。具體動作是接收到FIN,同時發送ack。(之所以叫close_wait可以理解爲被動關閉方此時正在等待上層應用發出關閉連接指令)

9.LAST_ACK:被動關閉的一方,發起關閉請求,由狀態close_wait進入此狀態。具體動作是發送FIN給對方,同時在接收到ACK進入CLOSED狀態。

10.CLOSING:兩邊同時發起關閉請求,會由FIN_WAIT_1進入此狀態。具體動作是接收到FIN請求,同時相應一個ACK。

11.TIME_WAIT:最糾結的狀態來了。從狀態圖上可以看出,有三個狀態可以轉化成它:

a:由FIN_WAIT_2進入此狀態:在雙方不同時發起FIN的情況下,主動關閉的一方在完成自身發起的關閉請求後,接收到被動關閉一方的FIN後進入的狀態。

b:由CLOSING狀態進入:雙方同時發起關閉,都做了發起FIN的請求,同時接收到了FIN並做了ACK的情況下,有CLOSING狀態進入。

c:由FIN_WAIT_1狀態進入:同時接收到FIN(對方發起),ACK(本身發起的FIN迴應),與b的區別在於本身發起的FIN迴應的ACK先於對方的FIN請求到達,而b是FIN先到達。這種情況概率最小。

關閉的4次連接最難理解的狀態是TIME_WAIT,存在TIME_WAIT的2個理由:

1.可靠地實現TCP全雙工連接的終止。

2.允許老的重複分節在網絡中消逝。

問題:TCP建立連接時,爲什麼是 三次握手呢?

client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認爲是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用“三次握手”,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以爲新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛纔那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。”在google上搜到的網友的解釋:

這個問題的本質是, 信道不可靠, 但是通信雙發需要就某個問題達成一致. 而要解決這個問題, 無論你在消息中包含什麼信息, 三次通信是理論上的最小值. 所以三次握手不是TCP本身的要求, 而是爲了滿足"在不可靠信道上可靠地傳輸信息"這一需求所導致的. 請注意這裏的本質需求,信道不可靠, 數據傳輸要可靠. 三次達到了, 那後面你想接着握手也好, 發數據也好, 跟進行可靠信息傳輸的需求就沒關係了. 因此,如果信道是可靠的, 即無論什麼時候發出消息, 對方一定能收到, 或者你不關心是否要保證對方收到你的消息, 那就能像UDP那樣直接發送消息就可以了.”

爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?
這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?
這是因爲:雖然雙方都同意關閉連接了,而且握手的4個報文也都協調和發送完畢,按理可以直接回到CLOSED狀態(就好比從SYN_SEND狀態到 ESTABLISH狀態那樣);但是因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於 LAST_ACK狀態下的SOCKET可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的 ACK報文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章