TCP三次握手四次揮手詳解

TCP三次握手

所謂三次握手(Three-way Handshake),是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。

三次握手的目的是連接服務器指定端口,建立TCP連接,並同步連接雙方的序列號和確認號並交換 TCP 窗口大小信息.在socket編程中,客戶端執行connect()時。將觸發三次握手。

這裏寫圖片描述

第一次握手:
客戶端發送一個TCP的SYN標誌位置1的包指明客戶打算連接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段裏。
建立連接時,客戶端A發送SYN包(SYN=j)到服務器B,並進入SYN_SEND狀態,等待服務器B確認。

這裏寫圖片描述

第二次握手:
服務器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均爲1同時,將確認序號(Acknowledgement Number)設置爲客戶的I S N加1以.即X+1。
服務器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器B進入SYN_RECV狀態。

這裏寫圖片描述

第三次握手.
客戶端再次發送確認包(ACK) SYN標誌位爲0,ACK標誌位爲1.並且把服務器發來ACK的序號字段+1,放在確定字段中發送給對方.並且在數據段放寫ISN的+1。
客戶端A收到服務器B的SYN+ACK包,向服務器B發送確認包ACK(ACK=k+1),此包發送完畢,客戶端A和服務器B進入ESTABLISHED狀態,完成三次握手。

這裏寫圖片描述

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攻擊。

TCP 四次揮手

TCP的連接的拆除需要發送四個包,因此稱爲四次揮手(four-way handshake)。客戶端或服務器均可主動發起揮手動作,在socket編程中,任何一方執行close()操作即可產生揮手操作。

這裏寫圖片描述

由於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)。

一些問題

1.爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

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

2.爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到CLOSED狀態?

TIME_WAIT狀態由兩個存在的理由。

(1)可靠的實現TCP全雙工鏈接的終止。

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

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

假 設在12.106.32.254的1500端口和206.168.1.112.219的21端口之間有一個TCP連接。我們關閉這個鏈接,過一段時間後在 相同的IP地址和端口建立另一個連接。後一個鏈接成爲前一個的化身。因爲它們的IP地址和端口號都相同。TCP必須防止來自某一個連接的老的重複分組在連 接已經終止後再現,從而被誤解成屬於同一鏈接的某一個某一個新的化身。爲做到這一點,TCP將不給處於TIME_WAIT狀態的鏈接發起新的化身。既然 TIME_WAIT狀態的持續時間是MSL的2倍,這就足以讓某個方向上的分組最多存活msl秒即被丟棄,另一個方向上的應答最多存活msl秒也被丟棄。 通過實施這個規則,我們就能保證每成功建立一個TCP連接時。來自該鏈接先前化身的重複分組都已經在網絡中消逝了。

  1. 爲什麼不能用兩次握手進行連接?

我們知道,3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。
現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作爲例子,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

常見面試題

1.TCP協議和UDP協議的區別是什麼

TCP協議是有連接的,有連接的意思是開始傳輸實際數據之前TCP的客戶端和服務器端必須通過三次握手建立連接,會話結束之後也要結束連接。而UDP是無連接的
TCP協議保證數據按序發送,按序到達,提供超時重傳來保證可靠性,但是UDP不保證按序到達,甚至不保證到達,只是努力交付,即便是按序發送的序列,也不保證按序送到。
TCP協議所需資源多,TCP首部需20個字節(不算可選項),UDP首部字段只需8個字節。
TCP有流量控制和擁塞控制,UDP沒有,網絡擁堵不會影響發送端的發送速率
TCP是一對一的連接,而UDP則可以支持一對一,多對多,一對多的通信。
TCP面向的是字節流的服務,UDP面向的是報文的服務。

2.請詳細介紹一下TCP協議建立連接和終止連接的過程?

這裏寫圖片描述

這裏寫圖片描述

3.三次握手建立連接時,發送方再次發送確認的必要性?

主要是爲了防止已失效的連接請求報文段突然又傳到了B,因而產生錯誤。假定出現一種異常情況,即A發出的第一個連接請求報文段並沒有丟失,而是在某些網絡結 點長時間滯留了,一直延遲到連接釋放以後的某個時間纔到達B,本來這是一個早已失效的報文段。但B收到此失效的連接請求報文段後,就誤認爲是A又發出一次 新的連接請求,於是就向A發出確認報文段,同意建立連接。假定不採用三次握手,那麼只要B發出確認,新的連接就建立了,這樣一直等待A發來數據,B的許多資源就這樣白白浪費了。

4.四次揮手釋放連接時,等待2MSL的意義?

第 一,爲了保證A發送的最有一個ACK報文段能夠到達B。這個ACK報文段有可能丟失,因而使處在LAST-ACK狀態的B收不到對已發送的FIN和ACK 報文段的確認。B會超時重傳這個FIN和ACK報文段,而A就能在2MSL時間內收到這個重傳的ACK+FIN報文段。接着A重傳一次確認。
第二,就是防止上面提到的已失效的連接請求報文段出現在本連接中,A在發送完最有一個ACK報文段後,再經過2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。

5.常見的應用中有哪些是應用TCP協議的,哪些又是應用UDP協議的,爲什麼它們被如此設計?

以下應用一般或必須用udp實現?
多播的信息一定要用udp實現,因爲tcp只支持一對一通信。
如果一個應用場景中大多是簡短的信息,適合用udp實現,因爲udp是基於報文段的,它直接對上層應用的數據封裝成報文段,然後丟在網絡中,如果信息量太大,會在鏈路層中被分片,影響傳輸效率。
如果一個應用場景重性能甚於重完整性和安全性,那麼適合於udp,比如多媒體應用,缺一兩幀不影響用戶體驗,但是需要流媒體到達的速度快,因此比較適合用udp
如果要求快速響應,那麼udp聽起來比較合適
如果又要利用udp的快速響應優點,又想可靠傳輸,那麼只能考上層應用自己制定規則了。
常見的使用udp的例子:ICQ,QQ的聊天模塊。

以qq爲例的一個說明
登陸採用TCP協議和HTTP協議,你和好友之間發送消息,主要採用UDP協議,內網傳文件採用了P2P技術。總來的說:
1.登陸過程,客戶端client 採用TCP協議向服務器server發送信息,HTTP協議下載信息。登陸之後,會有一個TCP連接來保持在線狀態。
2.和好友發消息,客戶端client採用UDP協議,但是需要通過服務器轉發。騰訊爲了確保傳輸消息的可靠,採用上層協議來保證可靠傳輸。如果消息發送失敗,客戶端會提示消息發送失敗,並可重新發送。
3.如果是在內網裏面的兩個客戶端傳文件,QQ採用的是P2P技術,不需要服務器中轉。

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