握手為什么需要三次己莺?
1、兩次只能保證服務器能夠接收到客戶端發(fā)送的信息建峭,不能保證客戶端能夠接收到服務器發(fā)送的信息。
2决摧、防止失效的連接請求報文段重新建立起新的連接亿蒸。
謝希仁版《計算機網(wǎng)絡》中的例子是這樣的,“已失效的連接請求報文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個連接請求報文段并沒有丟失掌桩,而是在某個網(wǎng)絡結(jié)點長時間的滯留了边锁,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段波岛。但server收到此失效的連接請求報文段后茅坛,就誤認為是client再次發(fā)出的一個新的連接請求。于是就向client發(fā)出確認報文段盆色,同意建立連接灰蛙。假設不采用“三次握手”祟剔,那么只要server發(fā)出確認隔躲,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求物延,因此不會理睬server的確認宣旱,也不會向server發(fā)送數(shù)據(jù)。但server卻以為新的運輸連接已經(jīng)建立叛薯,并一直等待client發(fā)來數(shù)據(jù)浑吟。這樣,server的很多資源就白白浪費掉了耗溜。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生组力。例如剛才那種情況,client不會向server的確認發(fā)出確認抖拴。server由于收不到確認燎字,就知道client并沒有要求建立連接腥椒。”
揮手為什么需要四次候衍?
過程:
1笼蛛、當主機A確認發(fā)送完數(shù)據(jù)且知道B已經(jīng)接收完畢,想要關閉發(fā)送數(shù)據(jù)口蛉鹿,就會發(fā)FIN給主機B滨砍。
2、主機B收到A發(fā)送的FIN妖异,表示收到了惋戏,就會發(fā)送ACK回復。
3随闺、但這是B可能還在發(fā)送數(shù)據(jù)日川,沒有想要關閉數(shù)據(jù)口的意思,所以FIN與ACK不是同時發(fā)送的矩乐,而是等到B數(shù)據(jù)發(fā)送完了龄句,才會發(fā)送FIN給主機A。
4散罕、A收到B發(fā)來的FIN分歇,知道B的數(shù)據(jù)也發(fā)送完了,回復ACK欧漱, A等待2MSL以后职抡,沒有收到B傳來的任何消息,知道B已經(jīng)收到自己的ACK了误甚,A就關閉鏈接缚甩,B也關閉鏈接了。
原因:
TCP采用的是全雙工傳輸窑邦,客戶端發(fā)出FIN后只是表明客戶端沒有數(shù)據(jù)需要發(fā)送了擅威,而服務器可能還有數(shù)據(jù)需要發(fā)送到客戶端。除非服務器也沒有數(shù)據(jù)需要發(fā)送到客戶端的話就會發(fā)送FIN+ACK冈钦,三次揮手關閉連接郊丛。
A為什么等待2MSL,從TIME_WAIT到CLOSE瞧筛?
TIME_WAIT作用:
1厉熟、保證最后一個ACK成功發(fā)送到客戶端。
2较幌、處理網(wǎng)絡殘留的報文揍瑟,避免新建立起的同端口的連接接收到舊的報文。(TCP稱為報文段乍炉,UDP稱為數(shù)據(jù)報)
在Client發(fā)送出最后的ACK回復绢片,但該ACK可能丟失嘁字。Server如果沒有收到ACK,將不斷重復發(fā)送FIN片段杉畜。所以Client不能立即關閉纪蜒,它必須確認Server接收到了該ACK。Client會在發(fā)送出ACK之后進入到TIME_WAIT狀態(tài)此叠。Client會設置一個計時器纯续,等待2MSL的時間。如果在該時間內(nèi)再次收到FIN灭袁,那么Client會重發(fā)ACK并再次等待2MSL猬错。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網(wǎng)絡中最大的存活時間茸歧,2MSL就是一個發(fā)送和一個回復所需的最大時間倦炒。如果直到2MSL,Client都沒有再次收到FIN软瞎,那么Client推斷ACK已經(jīng)被成功接收逢唤,則結(jié)束TCP連接。
Q
為什么TCP客戶端最后還要發(fā)送一次確認呢涤浇?
一句話鳖藕,主要防止已經(jīng)失效的連接請求報文突然又傳送到了服務器,從而產(chǎn)生錯誤只锭。
如果使用的是兩次握手建立連接著恩,假設有這樣一種場景,客戶端發(fā)送了第一個請求連接并且沒有丟失蜻展,只是因為在網(wǎng)絡結(jié)點中滯留的時間太長了喉誊,由于TCP的客戶端遲遲沒有收到確認報文,以為服務器沒有收到纵顾,此時重新向服務器發(fā)送這條報文伍茄,此后客戶端和服務器經(jīng)過兩次握手完成連接,傳輸數(shù)據(jù)片挂,然后關閉連接幻林。此時此前滯留的那一次請求連接贞盯,網(wǎng)絡通暢了到達了服務器音念,這個報文本該是失效的,但是躏敢,兩次握手的機制將會讓客戶端和服務器再次建立連接闷愤,這將導致不必要的錯誤和資源的浪費。
如果采用的是三次握手件余,就算是那一次失效的報文傳送過來了讥脐,服務端接受到了那條失效報文并且回復了確認報文遭居,但是客戶端不會再次發(fā)出確認。由于服務器收不到確認旬渠,就知道客戶端并沒有請求連接俱萍。
為什么客戶端最后還要等待2MSL?
MSL(Maximum Segment Lifetime)告丢,TCP允許不同的實現(xiàn)可以設置不同的MSL值枪蘑。
第一,保證客戶端發(fā)送的最后一個ACK報文能夠到達服務器岖免,因為這個ACK報文可能丟失岳颇,站在服務器的角度看來,我已經(jīng)發(fā)送了FIN+ACK報文請求斷開了颅湘,客戶端還沒有給我回應话侧,應該是我發(fā)送的請求斷開報文它沒有收到,于是服務器又會重新發(fā)送一次闯参,而客戶端就能在這個2MSL時間段內(nèi)收到這個重傳的報文瞻鹏,接著給出回應報文,并且會重啟2MSL計時器鹿寨。
第二乙漓,防止類似與“三次握手”中提到了的“已經(jīng)失效的連接請求報文段”出現(xiàn)在本連接中∈鸵疲客戶端發(fā)送完最后一個確認報文后叭披,在這個2MSL時間中,就可以使本連接持續(xù)的時間內(nèi)所產(chǎn)生的所有報文段都從網(wǎng)絡中消失玩讳。這樣新的連接中不會出現(xiàn)舊連接的請求報文涩蜘。
為什么建立連接是三次握手,關閉連接卻是四次揮手呢熏纯?
建立連接的時候同诫, 服務器在LISTEN狀態(tài)下,收到建立連接請求的SYN報文后樟澜,把ACK和SYN放在一個報文里發(fā)送給客戶端误窖。
而關閉連接時,服務器收到對方的FIN報文時秩贰,僅僅表示對方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)霹俺,而自己也未必全部數(shù)據(jù)都發(fā)送給對方了,所以己方可以立即關閉毒费,也可以發(fā)送一些數(shù)據(jù)給對方后丙唧,再發(fā)送FIN報文給對方來表示同意現(xiàn)在關閉連接,因此觅玻,己方ACK和FIN一般都會分開發(fā)送想际,從而導致多了一次培漏。
如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦胡本?
TCP還設有一個迸票活計時器,顯然侧甫,客戶端如果出現(xiàn)故障友鼻,服務器不能一直等下去,白白浪費資源闺骚。服務器每收到一次客戶端的請求后都會重新復位這個計時器彩扔,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數(shù)據(jù)僻爽,服務器就會發(fā)送一個探測報文段虫碉,以后每隔75分鐘發(fā)送一次。若一連發(fā)送10個探測報文仍然沒反應胸梆,服務器就認為客戶端出了故障敦捧,接著就關閉連接。