三次握手、四次揮手以及TCP標誌位的詳細介紹

一、TCP標誌位

在講TCP三次握手和四次揮手之前,先說一下TCP標誌位,方便後續的理解。

簡單來說,TCP標誌位的值代表了當前請求的目的。

標誌位一共有6種,分別是:

  1. SYN(synchronous): 發送/同步標誌,用來建立連接,和下面的第二個標誌位ACK搭配使用。連接開始時,SYN=1,ACK=0,代表連接開始但是未獲得響應。當連接被響應的時候,標誌位會發生變化,其中ACK會置爲1,代表確認收到連接請求,此時的標誌位變成了 SYN=1,ACK=1。
  2. ACK(acknowledgement):確認標誌,表示確認收到請求。
  3. PSH(push) :表示推送操作,就是指數據包到達接收端以後,不對其進行隊列處理,而是儘可能的將數據交給應用程序處理;
  4. FIN(finish):結束標誌,用於結束一個TCP會話;
  5. RST(reset):重置復位標誌,用於復位對應的TCP連接。
  6. URG(urgent):緊急標誌,用於保證TCP連接不被中斷,並且督促中間層設備儘快處理。

此外,還有兩個序號:

  1. Sequence number :順序號,發送數據包中的第一個字節的序列號,一般爲小寫的seq。
  2. Acknowledge number:確認號,響應前面的seq,值爲seq+1,可以理解爲期望下次發出的序列號爲seq+1;

二、TCP三次握手

1.TCP三次握手概述

所謂三次握手(Three-way Handshake),是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。 三次握手的目的是連接服務器指定端口,建立TCP連接,並同步連接雙方的順序號和確認號並交換 TCP信息

2.圖解TCP三次握手

  • 第一次握手:客戶端Client發送位碼爲SYN=1,隨機產生seq=x的數據包到服務器,服務器Server由SYN=1知道,客戶端Client要求建立聯機;
  • 第二次握手:服務器Server收到請求後要確認聯機信息,向客戶端Client發送ack=(客戶端Client請求連接時的seq)+1,SYN=1,ACK=1,產生seq=y的包,代表接收到連接請求並且向客戶端再次確認;
  • 第三次握手:客戶端Client收到後檢查ack是否正確,即第一次發送的seq+1,以及位碼ACK是否爲1,代表收到了服務器端發過來的確認信息。之後客戶端Client會再向服務器發送ack=(服務器Server的seq+1),ACK=1,服務器Server收到後確認ack 值與ACK=1,連接建立成功。

3.針對TCP連接的安全問題:SYN攻擊

  • 危害:SYN攻擊屬於DOS攻擊的一種,它利用TCP協議缺陷,通過發送大量的半連接請求,耗費CPU和內存資源。SYN攻擊除了能影響主機外,還可以危害路由器、防火牆等網絡系統,事實上SYN攻擊並不管目標是什麼系統,只要這些系統打開TCP服務就可以實施。
  • 原理:在三次握手過程中,服務器發送SYN-ACK(確認收到客戶端請求的連接)之後,收到客戶端的ACK(第三個包)之前的TCP連接稱爲半連接(half-open connect).此時服務器處於SYN_RECV(等待客戶端相應)狀態,如果接收到客戶端的ACK,則TCP連接成功,如果未接受到,則會重發請求直至成功。SYN攻擊就是 攻擊客戶端 在短時間內僞造大量不存在的IP地址,向服務器不斷地發送SYN包,服務器回覆確認包,並等待客戶的確認,由於源地址是不存在的,服務器需要不斷的重發直 至超時,這些僞造的SYN包將長時間佔用未連接隊列,影響了正常的SYN,目標系統運行緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。
  • 檢測:檢測SYN攻擊非常的方便,當在服務器上看到大量的半連接狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊。
  • 防範:主要有兩大類,一類是通過防火牆、路由器等過濾網關防護,另一類是通過加固TCP/IP協議棧防範.但必須清楚的是,SYN攻擊不能完全被阻止,我們所做的是儘可能的減輕SYN攻擊的危害,除非將TCP協議重新設計。

過濾網關防護:

  1. 網關超時設置
  2. SYN網關
  3. SYN代理

加固TCP/IP協議棧:

  1. SynAttackProtect機制
  2. SYN cookies技術
  3. 增加最大半連接數
  4. 縮短超時時間

三、圖解TCP四次揮手

  1. 客戶端Client進程發出連接釋放報文,並且停止發送數據。其中FIN=1,順序號爲seq=m(等於前面已經傳送過來的數據的最後一個字節的序號加1),此時,客戶端Client進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
  2. 服務器Server收到連接釋放報文,發出確認報文,ACK=1,ack=m+1,並且帶上自己的順序號seq=n,此時,服務器Server就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端Client向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端Client已經沒有數據要發送了,但是服務器Server若發送數據,客戶端Client依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
  3. 客戶端Client收到服務器Server的確認信息後,此時,客戶端Client就進入FIN-WAIT-2(終止等待2)狀態,等待服務器Server發送連接釋放報文(在這之前還需要接受服務器Server發送的最後的數據)。
  4. 服務器Server將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=m+1,由於在半關閉狀態,服務器Server很可能又發送了一些數據,假定此時的順序號爲seq=p,此時,服務器Server就進入了LAST-ACK(最後確認)狀態,等待客戶端Client的確認。
  5. 客戶端Client收到服務器Server的連接釋放報文後,必鬚髮出確認,ACK=1,ack=p+1,而自己的順序號是seq=m+1,此時,客戶端Client就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2*MSL(最長報文段壽命)的時間後,當客戶端Client撤銷相應的TCB(保護程序)後,才進入CLOSED狀態。
  6. 服務器Server只要收到了客戶端Client發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器Server結束TCP連接的時間要比客戶端Client早一些。

四、常見面試題

1.爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?

答:因爲當客戶端發起關閉連接的請求時,發出的FIN,僅代表客戶端沒有需要發送給服務器端的數據了。而如果服務器端如果仍有數據需要發送給客戶端的話,響應報文ACK和結束報文FIN則就不能同時發送給客戶端了。此時,服務器端會先返回一個響應報文,代表接收到了客戶端發出的FIN請求,而後在數據傳輸完了之後,再發出FIN請求,表示服務器端已經準備好斷開連接了。所以關閉連接的時候是四次握手。

2.爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:按照前面所說,當四個報文全部發送完畢後,理論上就算是結束了。但是實際情況往往不會那麼可靠,比如最後一條報文發出後丟失了,那麼服務器端就不會接收到這一報文,每隔一段時間,服務器端會再次發出FIN報文,此時如果客戶端已經斷開了,那麼就無法響應服務器的二次請求,這樣服務器會繼續發出FIN報文,從而變成了死循環。所以需要設置一個時間段,如果在這個時間段內接收到了服務器端的再次請求,則代表客戶端發出的ACK報文沒有接收成功。反之,則代表服務器端成功接收響應報文,客戶端進入CLOSED狀態,此次連接成功關閉。而這個時間,就規定爲了2MSL,即客戶端發出ACK報文到服務器端的最大時間 + 服務器沒有接收到ACK報文再次發出FIN的最大時間 = 2MSL

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

答:三次握手有兩個重要的功能,一是要雙方做好發送數據的準備工作且雙方都知道彼此已準備好,二要允許雙方就初始順序號進行協商,這個順序號在握手過程中被髮送和確認。如果改爲了兩次握手,是有可能發生死鎖的。在兩次握手的設定下,服務器端在成功接受客戶端的連接請求SYN後,向客戶端發出ACK確定報文時,如果因爲網絡原因客戶端沒有接收到,則會一直等待服務器端的ACK報文,而服務器端則認爲連接成功建立了,便開始向客戶端發送數據。但是客戶端因爲沒有收到服務器端的ACK報文,且不知道服務器的順序號seq,則會認爲連接未成功建立,忽略服務器發出的任何數據。如此客戶端一直等待服務器端的ACK報文,而服務器端因爲客戶端一直沒有接收數據,而不斷地重複發送數據,從而造成死鎖。

4.如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

答:TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

你好!我是 JHCan333,公衆號:愛生活的前端狗的作者。公衆號專注前端工程師方向,包括但不限於技術提高、職業規劃、生活品質、個人理財等方面,會持續發佈優質文章,從各個方面提升前端開發的幸福感。關注公衆號,我們一起向前走!

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