TCP三次握手四次揮手

TCP三次握手四次揮手詳解

相對於SOCKET開發者,TCP創建過程和鏈接折除過程是由TCP/IP協議棧自動創建的.因此開發者並不需要控制這個過程.但是對於理解TCP底層運作機制,相當有幫助.

而且對於有網絡協議工程師之類筆試,幾乎是必考的內容.企業對這個問題熱情之高,出乎我的意料:-)。有時上午面試前強調這個問題,並重復講一次,下午幾乎每一個人都被問到這個問題。

因此在這裏詳細解釋一下這兩個過程。

TCP三次握手

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

三次握手的目的是連接服務器指定端口,建立TCP連接,並同步連接雙方的序列號和確認號並交換 TCP 窗口大小信息.在socket編程中,客戶端執行connect()時。將觸發三次握手。
100327002629
第一次握手:
客戶端發送一個TCP的SYN標誌位置1的包指明客戶打算連接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段裏。
100327002911
第二次握手:
服務器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均爲1同時,將確認序號(Acknowledgement Number)設置爲客戶的I S N加1以.即X+1。
100327003054

第三次握手.
客戶端再次發送確認包(ACK) SYN標誌位爲0,ACK標誌位爲1.並且把服務器發來ACK的序號字段+1,放在確定字段中發送給對方.並且在數據段放寫ISN的+1
100327003214
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()操作即可產生揮手操作。

100327022731

第二部分:補充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狀態,完成三次握手。

完成三次握手,客戶端與服務器開始傳送數據。

​ 圖1 TCP三次握手建立連接

由於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採用四次揮手關閉連接如圖2所示。

​ 圖2 TCP四次揮手關閉連接

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

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

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

這個問題可以參考《unix 網絡編程》(第三版,2.7 TIME_WAIT狀態)。

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連接時。來自該鏈接先前化身的重複分組都已經在網絡中消逝了。

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

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

甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

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