建立tcp連接需要三次握手,斷開連接需要4次汰瘫。
三次握手:首先Client端發(fā)送連接請求報文箕憾,Server段接受連接后回復ACK報文,并為這次連接分配資源伦连。Client端接收到ACK報文后也向Server段發(fā)生ACK報文雨饺,并分配資源,這樣TCP連接就建立了惑淳。
為什么需要三次握手额港?
謝希仁版《計算機網絡》中的例子是這樣的,“已失效的連接請求報文段”的產生在這樣一種情況下:client發(fā)出的第一個連接請求報文段并沒有丟失歧焦,而是在某個網絡結點長時間的滯留了移斩,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段绢馍。但server收到此失效的連接請求報文段后向瓷,就誤認為是client再次發(fā)出的一個新的連接請求。于是就向client發(fā)出確認報文段痕貌,同意建立連接风罩。假設不采用“三次握手”糠排,那么只要server發(fā)出確認舵稠,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求入宦,因此不會理睬server的確認哺徊,也不會向server發(fā)送ack包。server卻以為新的運輸連接已經建立乾闰,并一直等待client發(fā)來數(shù)據(jù)落追。這樣,server的很多資源就白白浪費掉了涯肩。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生轿钠。例如剛才那種情況,client不會向server的確認發(fā)出確認病苗。server由于收不到確認疗垛,就知道client并沒有要求建立連接。在謝希仁著《計算機網絡》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端硫朦,因而產生錯誤”贷腕。在另一部經典的《計算機網絡》一書中講“三次握手”的目的是為了解決“網絡中存在延遲的重復分組”的問題。這兩種不同的表述其實闡明的是同一個問題。
那如何斷開連接呢泽裳?簡單的過程如下
1.假設客戶端主動斷開連接瞒斩,向服務器發(fā)送fin報文,這個報文主要告訴服務器客戶端已經沒有數(shù)據(jù)想要傳給服務器涮总,但是服務器你如果有數(shù)據(jù)沒傳輸完的話胸囱,先不用斷開socket連接,可以繼續(xù)發(fā)你的數(shù)據(jù)妹卿,先給客戶端發(fā)ack報文旺矾。2.服務器收到報文,看了fin的報文夺克,給客戶端發(fā)了ack報文箕宙,告訴客戶端服務器已經收到了消息,但我還有事沒做完铺纽,讓客戶端等會柬帕。3.這時候客戶端進入FIN_WAIT狀態(tài),即等待服務器給他發(fā)fin報文狡门。當服務器確定傳輸?shù)臄?shù)據(jù)都發(fā)完了陷寝,再向客戶端發(fā)送fin報文。告訴客戶端我已經傳輸完所有數(shù)據(jù)了其馏,可以關閉socket連接凤跑。4.客戶端收到fin報文,就知道socket要斷開連接了叛复,向服務器發(fā)送ack報文仔引,但客戶端不確定這個報文是否傳到服務器了,于是進入Time_wait狀態(tài)褐奥,如果服務器沒有收到ack報文則進行重傳咖耘,如果等待30s沒有收到消息說明連接服務器端已經關閉了,客戶端可以安心關閉了撬码。這樣tcp就斷開了儿倒。
【注意】在TIME_WAIT狀態(tài)中,如果TCP client端最后一次發(fā)送的ACK丟失了呜笑,它將重新發(fā)送夫否。TIME_WAIT狀態(tài)中所需要的時間是依賴于實現(xiàn)方法的。典型的值為30秒叫胁、1分鐘和2分鐘凰慈。等待之后連接正式關閉,并且所有的資源(包括端口號)都被釋放曹抬。
為什么連接的時候是三次握手溉瓶,關閉的時候卻是四次握手急鳄?
答:因為當Server端收到Client端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文堰酿。其中ACK報文是用來應答的疾宏,SYN報文是用來同步的。但是關閉連接時触创,當Server端收到FIN報文時坎藐,很可能并不會立即關閉SOCKET,所以只能先回復一個ACK報文哼绑,告訴Client端岩馍,"你發(fā)的FIN報文我收到了"。只有等到我Server端所有的報文都發(fā)送完了抖韩,我才能發(fā)送FIN報文蛀恩,因此不能一起發(fā)送。故需要四步握手茂浮。