關於三次握手與四次揮手你要知道這些

2022-07-09 04:12:15 字數 3225 閱讀 7381

如果沒有基礎的話,直接看這張圖或者網路上各種文字描述,十分生澀,所以先看懂接下來的握手揮手的圖,理解之後,再看這個有限狀態機就感覺原來如此簡單。

第一次握手:主機a傳送位碼為syn=1,隨機產生seq number=x的資料報到伺服器,客戶端進入syn_send狀態,等待伺服器的確認;主機b由syn=1知道a要求建立連線。

第二次握手:主機b收到請求後要確認連線資訊,向a傳送ack number(主機a的seq+1)、syn=1、ack=1,隨機產生seq=y的包,此時伺服器進入syn_recv狀態。

第三次握手:主機a收到後檢查ack number是否正確,即第一次傳送的seq number+1,以及位碼ack是否為1,若正確,主機a會再傳送ack number(主機b的seq+1)、ack=1,主機b收到後確認seq值與ack=1則連線建立成功。客戶端和伺服器端都進入established狀態。

第一次握手:客戶端傳送網路包,服務端收到了。這樣服務端就能得出結論:客戶端的傳送能力、服務端的接收能力是正常的。

第二次握手:服務端發包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的。不過此時伺服器並不能確認客戶端的接收能力是否正常。

第三次握手:客戶端發包,服務端收到了。這樣服務端就能得出結論:客戶端的接收能力,伺服器自己的傳送能力也正常。

至此,客戶端和服務端可以確定雙方的接收和傳送能力均正常。

這主要是為了防止已失效的連線請求報文段突然又傳送到了伺服器端,從而減少服務端的開銷。

如果只有兩次握手就建立連線會出現這種情況:客戶端發出的連線請求報文段在某些網路節點長時間滯留了,以致延誤到連線釋放以後的某個時間才能到達服務端。本來這是乙個早已失效的報文段,但服務端收到此失效的連線請求報文段後,就誤認為客戶端又發出了一次新的連線請求。於是向客戶端發出確認報文段,同意建立連線。由於現在客戶端並沒有發出建立連線的請求,因此不會處理服務端的確認,也不會向服務端傳送資料。但服務端卻以為新的連線已經建立了,並一直等待客戶端發來資料。 服務端會因此浪費很多了。

服務端:

該tcp連線的狀態為syn_recv,並且會根據tcp的超時重傳機制,會等待3秒、6秒、12秒後重新傳送syn+ack包,以便client重新傳送ack包。而server重發syn+ack包的次數,可以通過設定/proc/sys/net/ipv4/tcp_synack_retries修改,預設值為5。如果重發指定次數之後,仍然未收到客戶端的ack應答,那麼一段時間後,服務端自動關閉這個連線。

客戶端:

客戶端在接收到syn+ack包,它的tcp連線狀態就為established(已連線),表示該連線已經建立。那麼如果第三次握手中的ack包丟失的情況下,客戶端向服務端傳送資料,服務端將以rst包(reset重置)響應,才能感知到服務端的錯誤。

syn flood是一種經典的ddos攻擊手段,這裡面用到了tcp三次握手存在的漏洞。當服務端接收到syn後進入syn-recv狀態,此時的連線稱為半連線,同時會被服務端寫入乙個半連線佇列。如果攻擊者在短時間內不斷的向服務端傳送大量的syn包而不響應,那麼伺服器的半連線佇列很快會被寫滿,從而導致無法工作。 實現syn flood 的手段,可以通過偽造源ip的方式,這樣伺服器的響應就永遠到達不了客戶端(握手無法完成);當然,通過設定客戶端防火牆規則也可以達到同樣的目的。對syn flood實現攔截是比較困難的,可以通過啟用 syn_cookies 的方式實現緩解,但這通常不是最佳方案。最好的辦法是通過專業的防火牆來解決,基本上所有的雲計算大 都具備這個能力。

第一次揮手:主機a(可以是客戶端,也可以是伺服器端),設定sequence number和acknowledgment number,向主機b傳送乙個fin報文段;此時,主機a進入fin_wait_1狀態;這表示主機a沒有資料要傳送給主機b了。

第二次揮手:主機b收到了主機a傳送的fin報文段,向主機a回乙個ack報文段,acknowledgment number為sequence number加1,主機a進入fin_wait_2狀態;主機b告訴主機a,我也沒有資料要傳送了,可以進行關閉連線了。

第三次揮手:主機b向主機a傳送fin報文段,請求關閉連線,同時主機b進入close_wait狀態。

第四次揮手:主機a收到主機b傳送的fin報文段,向主機b傳送ack報文段,然後主機a進入time_wait狀態;主機b收到主機a的ack報文段以後,就關閉連線;此時,主機a等待2msl後依然沒有收到回覆,則證明主機b已正常關閉,那好,主機a也可以關閉連線了。

主機b傳送了fin-ack之後,會立即啟動超時重傳計時器

主機a在傳送最後乙個ack之後,會立即啟動時間等待計時器

因為當服務端收到客戶端的syn連線請求報文後,可以直接傳送syn+ack報文。其中ack報文是用來應答的,syn報文是用來同步的。但是關閉連線時,當服務端收到fin報文時,很可能並不會立即關閉socket,所以只能先回覆乙個ack報文,告訴客戶端,"你發的fin報文我收到了"。只有等到我服務端所有的報文都傳送完了,我才能傳送fin報文,因此不能一起傳送。故需要四次揮手。

rst 是乙個特殊的標記,用來表示當前應該立即終止連線。以下這些情況都會產生rst:

半關閉的狀態下的伺服器連線會處於closewait狀態,直到伺服器傳送了fin。 那麼在應用層則是呼叫socket.close()會執行fin的傳送,如果伺服器出現大量close_wait狀態的連線,那麼有可能的原因:

為了保證客戶端傳送的最後乙個ack報文段能夠到達伺服器。因為這個ack有可能丟失,從而導致處在last-ack狀態的伺服器收不到對fin-ack的確認報文。伺服器會超時重傳這個fin-ack,接著客戶端再重傳一次確認,重新啟動時間等待計時器。最後客戶端和伺服器都能正常的關閉。假設客戶端不等待2msl,而是在傳送完ack之後直接釋放關閉,一但這個ack丟失的話,伺服器就無法正常的進入關閉連線狀態。

msl是maximum segment lifetime的英文縮寫,可譯為「最長報文段壽命」,它是任何報文在網路上存在的最長時間,超過這個時間報文將被丟棄。我們都知道ip頭部中有個ttl欄位,ttl是time to live的縮寫,可譯為「生存時間」,這個生存時間是由源主機設定初始值代表乙個ip資料報可以經過的最大路由數,每經過乙個路由器,它的值就減1,當此值為0則資料報被丟棄,同時傳送icmp報文通知源主機。rfc793中規定msl為2分鐘,但這完全是從工程上來考慮,對於現在的網路,常用值30秒或1分鐘。因此tcp允許不同的實現可根據具體情況使用更小的msl值。

三次握手與四次揮手

1 三次握手是怎麼個意思?三次握手的是為了是建立可靠的通訊通道,簡單來說就是資料的傳送與接收,而三次握手最主要的目的就是雙方確認自己與對方的傳送與接收機能正常。這個三次握手只能是客戶端去發起,伺服器端接收確認的。正常來說伺服器是一直在監聽的,客戶端上線後去請求伺服器端,然後通過tcp協議進行連線。沒...

三次握手與四次揮手

三次握手與四次揮手分別對應tcp連線建立過程與斷開過程,先上tcp報文格式 三次握手過程 問題1 為什麼要三次握手?答 三次握手的目的是建立可靠的通訊通道,說到通訊,簡單來說就是資料的傳送與接收,而三次握手最主要的目的就是雙方確認自己與對方的傳送與接收機能正常。第一次握手 client什麼都不能確認...

三次握手與四次揮手

三次握手 1.定義 三次握手 three times handshake three way handshake 所謂的 三次握手 即對每次傳送的資料量是怎樣跟蹤進行協商使資料段的傳送和接收同步,根據所接收到的資料量而確定的資料確認數及資料傳送 接收完畢後何時撤消聯絡,並建立虛連線。2.為什麼要三次...