總結TCP為什麼三次握手四次揮手

2022-05-28 16:27:10 字數 2846 閱讀 4842

2019/3/4更新:

在閱讀了很多技術部落格後,發先大家對為什麼三次握手不是兩次眾說紛紜;我覺得說的最好的是英文文章對tcp的解讀。tcp和udp的區別就是可靠與不可靠傳輸。

為了實現可靠資料傳輸, tcp 協議的通訊雙方, 都必須維護各自的乙個序列號, 以標識傳送出去的資料報中, 哪些是已經被對方收到的。 三次握手的過程即是通訊雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟。

在這過程中序號seq和確認號ack使用是核心。(詳情請看下文)

如果只是兩次握手, 至多只有連線發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。

補充:第一次握手:a傳給b包丟了的話,a會週期性重傳,直到收到b的確認。

第二次握手:b回傳給a的序號+確認號包,a沒有收到,b會週期性重傳,直到收到a的確認。

第三次握手:a發給b的包丟失

a發完包後,單方面認為tcp是連線成功了,但是b只認為tcp是活躍狀態。

情況1:假設雙方沒有資料要傳送,b會重傳,知道再收到a的確認。收到之後ab確認連線成功。

情況2:a有資料傳送,b收到a的資料和確認包,會認為tcp連線成功。並接收a資料。

往期:首先要了解三次握手的具體過程:

為了建立客戶端和服務端的資料連線進行tcp的三次互動

(1)第一次握手:建立連線時,client端傳送給server端乙個syn包(標識位syn=1和client的初始序列號seq=x,此時標識位ack確認號=0,表示這是乙個tcp連線請求資料報文),並進入syn_sent狀態,等待server端確認。

(2)第二次握手:server端收到c端的發來的syn包(即收到c端發來的連線請求),同時自己也傳送乙個syn+ack包(標識位syn和ack都置1,表示這是確認報文。server.seq=y,以及server對client初始序號的確認號server.ack=client.seq+1=x+1)。

(3)第三次握手:client收到server的syn+ack包,並向server傳送乙個序列號(client.seq=x+1),確認號為ack(client.ack=server.seq+1=y+1),此包傳送完畢,客戶端和伺服器進入estab_lished(tcp連線成功)狀態,完成三次握手。

為什麼是三次:如果只有兩次(也就是客戶端傳送—服務端收到並傳送—客戶端收到)這個過程。假如服務端發出來的資料客戶端沒有收到呢(資料丟失的情況)? 客戶端等待一段時間後,會重新建立連線,即重新傳送連線請求。如果這個過程重複很多次,那麼就會產生非常多的無效連線,占用大量資源,甚至導致伺服器崩潰(也就是「syn洪水攻擊」現象)。

第三次握手,就是為了防止 因資料丟失或者資料傳輸延遲,導致客戶端重啟連線的現象。這也就防止了因伺服器收到過的無效鏈結而占用大量資源。

為什麼不是四次或五次?  對於tcp連線過程即c—>s—>c;如果是四次握手那麼會產生和兩次握手同樣的無效化連線現象,而且比兩次握手更浪費時間的資源。 那麼你也就知道了為什麼不五次握手,三次五次七次都可以做到確認並連線成功,為什麼不用最少的時間和資源呢?

第一次揮手:首先,client端傳送乙個fin (用來釋放乙個連線。fin=1表示:此報文段的傳送方的資料已經傳送完畢,並要求釋放運輸連線),用來關閉client端到server的資料傳送,然後等待server端的確認。其中終止標誌位fin=1,序列號seq=u。

第二次揮手:當server收到這個fin後,它會傳送乙個ack,確認號ack(ack=client.seq+1=u+1),序列號seq=v,確認已經收到了client端的終止請求。

第三次揮手:關閉伺服器到客戶端的連線,傳送乙個fin給客戶端,fin=1,更新的序列號seq=w,確認號ack=u+1(和第二次揮手相同)。

第四次揮手:當client收到fin後,並發回乙個ack報文確認已經收到,其中seq=u+1,ack=server.seq+1。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

總結全過程:客戶端第一次傳送fin後,進入終止等待狀態,伺服器收到客戶端連線釋放報文段後,就立即給客戶端傳送確認,伺服器就進入close_wait狀態,此時tcp伺服器程序就通知高層應用程序,因而從客戶端到伺服器的連線就釋放了。此時是「半關閉狀態」,即客戶端不可以傳送給伺服器,伺服器可以傳送給客戶端。此時,如果伺服器沒有資料報傳送給客戶端,其應用程式就通知tcp釋放連線,然後傳送給客戶端連線釋放資料報,並等待確認。客戶端傳送確認後,進入time_wait狀態,但是此時tcp連線還沒有釋放,然後經過等待計時器設定的2msl後,才進入到closed狀態。

為什麼連線的時候是三次握手,關閉的時候卻是四次握手?

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

為什麼最後會有客戶端等待2msl時間?

msl是最大報文生存時間。為了保證客戶端傳送的最後乙個ack報文段能夠到達伺服器。即最後乙個確認報文可能丟失,伺服器會超時重傳,然後伺服器傳送fin請求關閉連線,客戶端傳送ack確認。乙個來回是兩個報文生命週期。

如果沒有等待時間,傳送完確認報文段就立即釋放連線的話,伺服器就無法重傳,因此也就收不到確認,就無法按步驟進入closed狀態。

並且可以防止已經失效的連線請求報文出現在連線中。經過2msl,在這個連續持續的時間內,產生的所有報文段就可以都從網路消失。

TCP三次握手和四次揮

一 tcp報文格式 在了解三次握手和四次揮手之前,首先要知道tcp報文內部包含了哪些東西。報文主要段的含義 序號 seq 用來標記資料段的順序,確保tcp傳輸有序。ack 確認 確認序號標誌,ack 1表示確認號字段有效,ack 0表示確認序號無效。syn 同步 連線請求序號標誌,用於建立連線。sy...

三次握手和四次揮手 TCP三次握手和四次揮手的理解

相比較於udp傳輸協議,tcp傳輸協議被認為是安全可靠的,這是由於tcp協議的三次握手和四次揮手保證了資料傳輸的安全性。tcp報文格式簡介 要了解tcp協議的三次握手和四次揮手,需要先了解在tcp協議中請求和響應的資料報報文格式。在報文中有幾個值得注意的字段 1 序號 seq序號,佔32位,用來標識...

結合socket詳解TCP三次握手四次揮手

tcp協議中的三次握手和四次揮手大家應該都至少聽說過了,本人一直覺得理論學習要結合 才能學習的更深刻,當知道東西是這樣,然後再知道為什麼是這樣的時候,領悟往往更加深刻,今天本人就結合socket程式設計中的api來解析一下tcp協議的三次握手和四次揮手過程。那麼tcp協議中的三次握手和四次揮手實際在...