三次握手,四次揮手 具體發送的報文和狀態都要掌握(阿里)


如果想了解HTTP的協議結構,原理,post,get的區別(阿里面試題目),請參考:HTTP協議 結構,get post 區別(阿里面試) 

但是如果想進入阿里的話,還是看本文理解TCP的三次握手和四次揮手,發送的報文和狀態都要掌握,阿里問了好幾次了。

七層協議四層協議 參考:七層協議和四層協議 

TCP報文格式


TCP報文格式1.jpg

16位源端口號:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是標識報文的返回地址。

16位目的端口號:16位的目的端口域定義傳輸的目的。這個端口指明報文接收計算機上的應用程序地址接口。

32位序號:32位的序列號由接收端計算機使用,重新分段的報文成最初形式。當SYN出現,序列碼實際上是初始序列碼(Initial Sequence Number,ISN),而第一個數據字節是ISN+1。這個序列號(序列碼)可用來補償傳輸中的不一致。

32位確認序號:32位的序列號由接收端計算機使用,重組分段的報文成最初形式。如果設置了ACK控制位,這個值表示一個准備接收的包的序列碼。

4位首部長度:4位包括TCP頭大小,指示何處數據開始。

保留(6位):6位值域,這些位必須是0。為了將來定義新的用途而保留。

標志:6位標志域。表示為:緊急標志、有意義的應答標志、推、重置連接標志、同步序列號標志、完成發送數據標志。按照順序排列是:URG、ACK、PSH、RST、SYN、FIN。

16位窗口大小:用來表示想收到的每個TCP數據段的大小。TCP的流量控制由連接的每一端通過聲明的窗口大小來提供。窗口大小為字節數,起始於確認序號字段指明的值,這個值是接收端正期望接收的字節。窗口大小是一個16字節字段,因而窗口大小最大為65535字節。

16位校驗和:16位TCP頭。源機器基於數據內容計算一個數值,收信息機要與源機器數值 結果完全一樣,從而證明數據的有效性。檢驗和覆蓋了整個的TCP報文段:這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證的。

16位緊急指針:指向后面是優先數據的字節,在URG標志設置了時才有效。如果URG標志沒有被設置,緊急域作為填充。加快處理標示為緊急的數據段。

選項:長度不定,但長度必須為1個字節。如果沒有選項就表示這個1字節的域等於0。

數據:該TCP協議包負載的數據。

TCP標志位:

TCP共有6個標志位,分別是:

  • SYN(synchronous),建立聯機。
  • ACK(acknowledgement),確認。
  • PSH(push),傳輸。
  • FIN(finish),結束。
  • RST(reset),重置。
  • URG(urgent),緊急。 

URG:緊急標志。緊急標志為"1"表明該位有效。

ACK:確認標志。表明確認編號欄有效。大多數情況下該標志位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1)為下一個預期的序列編號,同時提示遠端系統已經成功接收所有數據。

PSH:推標志。該標志置位時,接收端不將該數據進行隊列處理,而是盡可能快地將數據轉由應用處理。在處理Telnet或rlogin等交互模式的連接時,該標志總是置位的。

RST:復位標志。用於復位相應的TCP連接。

SYN:同步標志。表明同步序列編號欄有效。該標志僅在三次握手建立TCP連接時有效。它提示TCP連接的服務端檢查序列編號,該序列編號為TCP連接初始端(一般是客戶端)的初始序列編號。在這里,可以把TCP序列編號看作是一個范圍從0到4,294,967,295的32位計數器。通過TCP連接交換的數據中每一個字節都經過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個字節的序列編號。

FIN:結束標志。

TCP三次握手

所謂三次握手(Three-Way Handshake)即建立TCP連接,就是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發,整個流程如下圖所示:


TCP三次握手.png

(1)第一次握手:Client將標志位SYN置為1,隨機產生一個值seq=J,並將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。

(2)第二次握手:Server收到數據包后由標志位SYN=1知道Client請求建立連接,Server將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態。

(3)第三次握手:Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,並將該數據包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨后Client與Server之間可以開始傳輸數據了。

簡單來說,就是

1、建立連接時,客戶端發送SYN包(SYN=i)到服務器,並進入到SYN-SEND狀態,等待服務器確認

2、服務器收到SYN包,必須確認客戶的SYN(ack=i+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器進入SYN-RECV狀態

3、客戶端收到服務器的SYN+ACK包,向服務器發送確認報ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手,客戶端與服務器開始傳送數據。

SYN網絡攻擊:

在三次握手過程中,Server發送SYN-ACK之后,收到Client的ACK之前的TCP連接稱為半連接(half-open connect),此時Server處於SYN_RCVD狀態,當收到ACK后,Server轉入ESTABLISHED狀態。SYN攻擊就是Client在短時間內偽造大量不存在的IP地址,並向Server不斷地發送SYN包,Server回復確認包,並等待Client的確認,由於源地址是不存在的,因此,Server需要不斷重發直至超時,這些偽造的SYN包將產時間占用未連接隊列,導致正常的SYN請求因為隊列滿而被丟棄,從而引起網絡堵塞甚至系統癱瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單,即當Server上有大量半連接狀態且源IP地址是隨機的,則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現行:

#netstat -nap | grep SYN_RECV  

檢測: 
SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單,即當Server上有大量半連接狀態且源IP地址是隨機的,則可以斷定遭到SYN攻擊了。windows下打開cmd,輸入命令:”netstat -n -p TCP“,查看是否有大量的”SYN_RECEIVED“狀態。

以下圖片是表明正常的。 

TCP四次揮手

所謂四次揮手(Four-Way Wavehand)即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發,整個流程如下圖所示:


TCP四次揮手.png

由於TCP連接時全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味着這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。

(1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。(狀態位FIN=1,發送seq=J)

(2)第二次揮手:Server收到FIN后,發送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態。(狀態位ACK=1,發送ack=J+1)

(3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。(狀態位FIN=1,發送seq=K)

(4)第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。(狀態位ACK=1,ack=K+1)

注意此時客戶端並未進入CLOSED狀態,為了防止服務延遲,需要等待2MSL的時間,然后進入CLOSED狀態,因為如果客戶端直接進入CLOSED了,如果網絡異常,客戶端就不能重重發數據。

 

為什么建立連接是三次握手,而關閉連接卻是四次揮手呢?

這是因為服務端在LISTEN狀態下,收到建立連接請求的SYN報文后,把ACK和SYN放在一個報文里發送給客戶端。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方也未必全部數據都發送給對方了,所以己方可以立即close,也可以發送一些數據給對方后,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送。 

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

原因有二:
一、保證TCP協議的全雙工連接能夠可靠關閉
二、保證這次連接的重復數據段從網絡中消失

先說第一點,如果Client直接CLOSED了,那么由於IP協議的不可靠性或者是其它網絡原因,導致Server沒有收到Client最后回復的ACK。那么Server就會在超時之后繼續發送FIN,此時由於Client已經CLOSED了,就找不到與重發的FIN對應的連接,最后Server就會收到RST而不是ACK,Server就會以為是連接錯誤把問題報告給高層。這樣的情況雖然不會造成數據丟失,但是卻導致TCP協議不符合可靠連接的要求。所以,Client不是直接進入CLOSED,而是要保持TIME_WAIT,當再次收到FIN的時候,能夠保證對方收到ACK,最后正確的關閉連接。

再說第二點,如果Client直接CLOSED,然后又再向Server發起一個新連接,我們不能保證這個新連接與剛關閉的連接的端口號是不同的。也就是說有可能新連接和老連接的端口號是相同的。一般來說不會發生什么問題,但是還是有特殊情況出現:假設新連接和已經關閉的老連接端口號是一樣的,如果前一次連接的某些數據仍然滯留在網絡中,這些延遲數據在建立新連接之后才到達Server,由於新連接和老連接的端口號是一樣的,又因為TCP協議判斷不同連接的依據是socket pair,於是,TCP協議就認為那個延遲的數據是屬於新連接的,這樣就和真正的新連接的數據包發生混淆了。所以TCP連接還要在TIME_WAIT狀態等待2倍MSL,這樣可以保證本次連接的所有數據都從網絡中消失。

 
這個問題也很好理解,當客戶端最終告訴服務器端斷開確認的時候,他不知道自己的發出的指令是否能准確的一次性被服務器接收。假如服務器沒有接收到(這已經耗費了一個報文的最大通信時間了),服務器端將會重新發起一個結束通話的指令(FIN)到客戶端,客戶端又接收到了服務器發來的結束通信指令將繼續給服務器進行一個確認,有人會說那要是客戶端發出的確認信息服務端沒收到,而服務端重發的斷開指令客戶端也沒收到怎么辦,說實話我也無奈,遇到這種情況咱們干脆認為網確實不行了。

TCP/IP協議三次握手和四次揮手大白話解說 

 前言 

TCP(Transmission Control Protocol)網絡傳輸控制協議,是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,數據傳輸前建立連接的工作要經過三次握手,數據傳輸后斷開連接的工作要經過四次揮手。

工作過程

三次握手建立連接闡述:

第一次握手:客戶端要和服務端進行通信,首先要告知服務端一聲,遂發出一個SYN=1的連接請求信號,”服務端哥哥,我想給你說說話”。

第二次握手:當服務端接收到客戶端的連接請求,此時要給客戶端一個確認信息,”我知道了(ACK),我這邊已經准備好了,你現在能連嗎(SYN)”。

第三次握手:當客戶端收到了服務端的確認連接信息后,要禮貌的告知一下服務端,“好的,咱們開始聯通吧(ACK)”。

到此整個建立連接的過程已經結束,接下來就是雙方你一句我一句甚至同時交流傳遞信息的過程了。

四次揮手斷開連接闡述:

第一次揮手:雙方交流的差不多了,此時客戶端也已經結尾了,接下來要斷開通信連接,所以告訴服務端“我說完了(FIN)”,此時自身形成等待結束連接的狀態。

第二次揮手:服務端知道客戶端已經沒話說了,服務端此時還有兩句心里話要給客戶端說,“我知道你說完了(ACK),我再給你說兩句,&*……%¥”。

第三次揮手:此時客戶端洗耳恭聽繼續處於等待結束的狀態,服務器端也說完了,自身此時處於等待關閉連接的狀態,並對告訴客戶端,“我說完了,咱們斷了吧(FIN)”。

第四次揮手:客戶端收知道服務端也說完了,也要告訴服務端一聲(ACK),因為連接和斷開要雙方都按下關閉操作才能斷開,客戶端同時又為自己定義一個定時器,因為不知道剛才說的這句話能不能准確到達服務端(網絡不穩定或者其他因素引起的網絡原因),默認時間定為兩個通信的最大時間之和,超出這個時間就默認服務器端已經接收到了自己的確認信息,此時客戶端就關閉自身連接,服務器端一旦接收到客戶端發來的確定通知就立刻關閉服務器端的連接。

到此為止雙方整個通信過程就此終結。這里要聲明一下:斷開鏈接不一定就是客戶端,誰都可以先發起斷開指令,另外客戶端和服務端是沒有固定標准的,誰先發起請求誰就是客戶端。 

附加

 在TIME_WAIT狀態中,如果TCP client端最后一次發送的ACK丟失了,它將重新發送。TIME_WAIT狀態中所需要的時間是依賴於實現方法的。典型的值為30秒、1分鍾和2分鍾。等待之后連接正式關閉,並且所有的資源(包括端口號)都被釋放。 

 參考:TCP/IP協議三次握手和四次揮手大白話解說

 參考:TCP協議詳解 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM