1. 程式人生 > >TCP協議特點和三次握手/四次揮手

TCP協議特點和三次握手/四次揮手

  • TCP的特性

TCP提供一種面向連線的、可靠的位元組流服務
在一個TCP連線中,僅有兩方進行彼此通訊。廣播和多播不能用於TCP
TCP使用校驗和,確認和重傳機制來保證可靠傳輸
TCP給資料分節進行排序,並使用累積確認保證資料的順序不變和非重複
TCP使用滑動視窗機制來實現流量控制,通過動態改變視窗的大小進行擁塞控制
注意:TCP 並不能保證資料一定會被對方接收到,因為這是不可能的。TCP 能夠做到的是,如果有可能,就把資料遞送到接收方,否則就(通過放棄重傳並且中斷連線這一手段)通知使用者。因此準確說 TCP 也不是 100% 可靠的協議,它所能提供的是資料的可靠遞送或故障的可靠通知。

  • 三次握手

  • 所謂三次握手(Three-way Handshake),是指建立一個 TCP 連線時,需要客戶端和伺服器總共傳送3個包。
  • 三次握手的目的是連線伺服器指定,建立 TCP 連線,並同步連線雙方的序列號和確認號,交換 TCP 視窗大小資訊。在 socket 程式設計中,客戶端執行 connect() 時。將觸發三次握手。

第一次握手(SYN=1, seq=x)
客戶端傳送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算連線的伺服器的埠,以及初始序號 X,儲存在包頭的序列號(Sequence Number)欄位裡。傳送完畢後,客戶端進入 SYN_SEND 狀態。

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1)
伺服器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均為1。伺服器端選擇自己 ISN 序列號,放到 Seq 域裡,同時將確認序號(Acknowledgement Number)設定為客戶的 ISN 加1,即X+1。 傳送完畢後,伺服器端進入 SYN_RCVD 狀態。

第三次握手(ACK=1,ACKnum=y+1)
客戶端再次傳送確認包(ACK),SYN 標誌位為0,ACK 標誌位為1,並且把伺服器發來 ACK 的序號欄位+1,放在確定欄位中傳送給對方,並且在資料段放寫ISN的+1傳送完畢後,客戶端進入 ESTABLISHED 狀態,當伺服器端接收到這個包時,也進入 ESTABLISHED 狀態,TCP 握手結束。

SYN攻擊
在三次握手過程中,伺服器傳送SYN-ACK之後,收到客戶端的ACK之前的TCP連線稱為半連線(half-open connect).此時伺服器處於Syn_RECV狀態.當收到ACK後,伺服器轉入ESTABLISHED狀態.
Syn攻擊就是 攻擊客戶端 在短時間內偽造大量不存在的IP地址,向伺服器不斷地傳送syn包,伺服器回覆確認包,並等待客戶的確認,由於源地址是不存在的,伺服器需要不斷的重發直 至超時,這些偽造的SYN包將長時間佔用未連線佇列,正常的SYN請求被丟棄,目標系統執行緩慢,嚴重者引起網路堵塞甚至系統癱瘓。
Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊非常的方便,當你在伺服器上看到大量的半連線狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊.在Linux下可以如下命令檢測是否被Syn攻擊
netstat -n -p TCP | grep SYN_RECV
一般較新的TCP/IP協議棧都對這一過程進行修正來防範Syn攻擊,修改tcp協議實現。主要方法有SynAttackProtect保護機制、SYN cookies技術、增加最大半連線和縮短超時時間等.
但是不能完全防範syn攻擊。

問題1: 為什麼要三次握手?

答:三次握手的目的是建立可靠的通訊通道,說到通訊,簡單來說就是資料的傳送與接收,而三次握手最主要的目的就是雙方確認自己與對方的傳送與接收機能正常。

        第一次握手:Client什麼都不能確認;Server確認了對方傳送正常

        第二次握手:Client確認了:自己傳送、接收正常,對方傳送、接收正常;Server確認了:自己接收正常,對方傳送正常

        第三次握手:Client確認了:自己傳送、接收正常,對方傳送、接收正常;Server確認了:自己傳送、接收正常,對方傳送接收正常

所以三次握手就能確認雙發收發功能都正常,缺一不可。

問題2:為什麼要傳送特定的資料包,隨便發不行嗎?

答:三次握手的另外一個目的就是確認雙方都支援TCP,告知對方用TCP傳輸。

        第一次握手:Server 猜測Client可能要建立TCP請求,但不確定,因為也可能是Client亂髮了一個數據包給自己

        第二次握手:通過ack=J+1,Client知道Server是支援TCP的,且理解了自己要建立TCP連線的意圖

        第三次握手:通過ack=K+1,Server知道Client是支援TCP的,且確實是要建立TCP連線

問題3:上圖中的SYN和ACK是什麼?

答:SYN是標誌位,SYN=1表示請求連線;

        ACK其實就是ack後面加上的那個數,真正傳送的時候不單獨發ACK,只發ack。

  • 四次揮手

TCP 的連線的拆除需要傳送四個包,因此稱為四次揮手(Four-way handshake),也叫做改進的三次握手。客戶端或伺服器均可主動發起揮手動作,在 socket 程式設計中,任何一方執行 close() 操作即可產生揮手操作。

第一次揮手(FIN=1,seq=x)
假設客戶端想要關閉連線,客戶端傳送一個 FIN 標誌位置為1的包,表示自己已經沒有資料可以傳送了,但是仍然可以接受資料。傳送完畢後,客戶端進入 FIN_WAIT_1 狀態。

第二次揮手(ACK=1,ACKnum=x+1)
伺服器端確認客戶端的 FIN 包,傳送一個確認包,表明自己接受到了客戶端關閉連線的請求,但還沒有準備好關閉連線。傳送完畢後,伺服器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包之後,進入 FIN_WAIT_2 狀態,等待伺服器端關閉連線。

第三次揮手(FIN=1,seq=y)
伺服器端準備好關閉連線時,向客戶端傳送結束連線請求,FIN 置為1。
傳送完畢後,伺服器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個ACK。

第四次揮手(ACK=1,ACKnum=y+1)
客戶端接收到來自伺服器端的關閉請求,傳送一個確認包,並進入 TIME_WAIT狀態,等待可能出現的要求重傳的 ACK 包。伺服器端接收到這個確認包之後,關閉連線,進入 CLOSED 狀態。客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到伺服器端的 ACK ,認為伺服器端已經正常關閉連線,於是自己也關閉連線,進入 CLOSED 狀態。

問題1: 為什麼要四次揮手?

答:確保資料能夠完整傳輸。

根本原因是,一方傳送FIN只表示自己發完了所有要發的資料,但還允許對方繼續把沒發完的資料發過來。

當被動方收到主動方的FIN報文通知時,它僅僅表示主動方沒有資料再發送給被動方了。

但未必被動方所有的資料都完整的傳送給了主動方,所以被動方不會馬上關閉SOCKET,它可能還需要傳送一些資料給主動方後,

再發送FIN報文給主動方,告訴主動方同意關閉連線,所以這裡的ACK報文和FIN報文多數情況下都是分開發送的。

 舉個例子:A和B打電話,通話即將結束後,A說“我沒啥要說的了”,B回答“我知道了”,但是B可能還會有要說的話,A不能要求B跟著自己的節奏結束通話,於是B可能又巴拉巴拉說了一通,最後B說“我說完了”,A回答“知道了”,這樣通話才算結束。

問題2:為什麼雙方要傳送這樣的資料包?

答:和握手的情況類似,只是為了讓對方知曉自己理解了對方的意圖。

  • 補充 TCP 連線過程

在TCP/IP協議中,TCP協議提供可靠的連線服務,採用三次握手建立一個連線,如圖1所示。

 (1) 第一次握手:建立連線時,客戶端A傳送SYN包(SYN=j)到伺服器B,並進入SYN_SEND狀態,等待伺服器B確認。

 (2) 第二次握手:伺服器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也傳送一個SYN包(SYN=k),即SYN+ACK包,此時伺服器B進入SYN_RECV狀態。

 (3) 第三次握手:客戶端A收到伺服器B的SYN+ACK包,向伺服器B傳送確認包ACK(ACK=k+1),此包傳送完畢,客戶端A和伺服器B進入ESTABLISHED狀態,完成三次握手。

完成三次握手,客戶端與伺服器開始傳送資料。

 

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

(1)客戶端A傳送一個FIN,用來關閉客戶A到伺服器B的資料傳送(報文段4)。

(2)伺服器B收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。和SYN一樣,一個FIN將佔用一個序號。

(3)伺服器B關閉與客戶端A的連線,傳送一個FIN給客戶端A(報文段6)。

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

  • 常見面試題

  • TCP協議和UDP協議的區別是什麼?
    • TCP提供了一種可靠的面向連線的位元組流運輸層服務。TCP將使用者資料打包成報文段,它傳送後啟動一個定時器,另一端收到的資料進行確認,對失序的資料重新排序,丟棄重複資料,TCP提供端到端的流量控制,並計算和驗證一個強制性的端到端的檢驗和。

    • 許多流行的應用程式如:Telnet, Rlogin, FTP,SMTP 都使用TCP。

    • TCP的主要特點:
      • TCP是面向連線的運輸層協議
      • 每一條TCP連線只能有兩個端點,每一條TCP連線只能是點對點的
      • TCP提供可靠交付的服務
      • TCP提供全雙工通訊
      • 面向位元組流。
      • 面向位元組流的含義:雖然應用程式和TCP互動是一次一個資料塊,但TCP把應用程式交下來的資料僅僅是一連串的無結構的位元組流
    • TCP面向的是位元組流的服務,UDP面向的是報文的服務。
    • TCP是一對一的連線,而UDP則可以支援一對一,多對多,一對多的通訊。
    • TCP有流量控制和擁塞控制,UDP沒有,網路擁堵不會影響傳送端的傳送速率
    • TCP協議所需資源多,TCP首部需20個位元組(不算可選項),UDP首部欄位只需8個位元組。
    • TCP協議保證資料按序傳送,按序到達,提供超時重傳來保證可靠性,但是UDP不保證按序到達,甚至不保證到達,只是努力交付,即便是按序傳送的序列,也不保證按序送到。
    • TCP協議是有連線的,有連線的意思是開始傳輸實際資料之前TCP的客戶端和伺服器端必須通過三次握手建立連線,會話結束之後也要結束連線。而UDP是無連線的
  • 常見的應用中有哪些是應用TCP協議的,哪些又是應用UDP協議的,為什麼它們被如此設計?
    • 以下應用一般或必須用udp實現?
      • 多播的資訊一定要用udp實現,因為tcp只支援一對一通訊。
      • 如果一個應用場景中大多是簡短的資訊,適合用udp實現,因為udp是基於報文段的,它直接對上層應用的資料封裝成報文段,然後丟在網路中,如果資訊量太大,會在鏈路層中被分片,影響傳輸效率。
      • 如果一個應用場景重效能甚於重完整性和安全性,那麼適合於udp,比如多媒體應用,缺一兩幀不影響使用者體驗,但是需要流媒體到達的速度快,因此比較適合用udp
      • 如果要求快速響應,那麼udp聽起來比較合適
      • 如果又要利用udp的快速響應優點,又想可靠傳輸,那麼只能考上層應用自己制定規則了。
      • 常見的使用udp的例子:ICQ,QQ的聊天模組。