概述
我們都知道 TCP 是 可靠的數(shù)據(jù)傳輸協(xié)議鸽素,UDP是不可靠傳輸褒繁,那么TCP它是怎么保證可靠傳輸?shù)哪兀磕俏覀兙筒坏貌惶?TCP 的三次握手和四次揮手馍忽。
三次握手
下圖為三次握手的流程圖
下面通過我們 wireshark 抓包工具來分析三次握手
第一次握手
建立連接澜汤《尕遥客戶端發(fā)送連接請求報(bào)文段,將SYN位置為1坐梯,Sequence Number為x;(x 是隨機(jī)生成的一個(gè) int 數(shù)值)然后谎替,客戶端進(jìn)入SYN_SEND狀態(tài)蹋辅,等待服務(wù)器的確認(rèn);
第二次握手
服務(wù)器收到SYN報(bào)文段秩命。服務(wù)器收到客戶端的SYN報(bào)文段,需要對這個(gè)SYN報(bào)文段進(jìn)行確認(rèn)袄友,設(shè)置Acknowledgment Number為x+1(Sequence Number+1)霹菊;同時(shí),自己自己還要發(fā)送SYN請求信息鸠按,將SYN位置為1饶碘,Sequence Number為 y (y 是隨機(jī)生存的一個(gè) int 數(shù)值);服務(wù)器端將上述所有信息放到一個(gè)報(bào)文段(即SYN+ACK報(bào)文段)中卑雁,一并發(fā)送給客戶端绪囱,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
第三次握手
客戶端收到服務(wù)器的SYN+ACK報(bào)文段扣甲。然后將Acknowledgment Number設(shè)置為y+1齿椅,向服務(wù)器發(fā)送ACK報(bào)文段,這個(gè)報(bào)文段發(fā)送完畢以后示辈,客戶端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài)遣蚀,完成TCP三次握手。
四次揮手
第一次揮手:
Client (可以使客戶端险耀,也可以是服務(wù)器端)甩牺,設(shè)置Sequence Number和Acknowledgment Number累奈,向 Server發(fā)送一個(gè)FIN報(bào)文段急但;此時(shí)赠群,Client 進(jìn)入FIN_WAIT_1狀態(tài)旱幼;這表示 Client 沒有數(shù)據(jù)要發(fā)送給 Server了;
客戶端發(fā)送第一次揮手后冬三,就不能在向 服務(wù)端發(fā)送數(shù)據(jù)了缘缚。
第二次揮手:
Server 收到了 Client 發(fā)送的FIN報(bào)文段,向 Client 回一個(gè)ACK報(bào)文段窝爪,Acknowledgment Number 為 Sequence Number 加 1齐媒;Client 進(jìn)入 FIN_WAIT_2 狀態(tài);Server 告訴 Client 邀杏,我“同意”你的關(guān)閉請求唬血;
Server 第一次響應(yīng)后,還可以繼續(xù)向 Client 發(fā)送數(shù)據(jù)拷恨,這里只是告訴 Client ,我收到你發(fā)送的關(guān)閉請求小泉。
第三次揮手
Server 向 Client 發(fā)送 FIN 報(bào)文段兜挨,請求關(guān)閉連接,同時(shí) Server 進(jìn)入 CLOSE_WAIT 狀態(tài)柒桑;
當(dāng) Server 的數(shù)據(jù)響應(yīng)完成后噪舀,再告訴 Client飘诗,我這邊也可以關(guān)閉請求了界逛, 這時(shí)
Server 就不能再向 Client 發(fā)送數(shù)據(jù)了
第四次揮手
Client 收到 Server 發(fā)送的 FIN 報(bào)文段昆稿,向 Server 發(fā)送 ACK 報(bào)文段溉潭,然后 Client 進(jìn)入
TIME_WAIT 狀態(tài)少欺;Server 收到 Client 的 ACK 報(bào)文段以后,就關(guān)閉連接畏陕;此時(shí)仿滔,Client
等待2MSL后依然沒有收到回復(fù),則證明 Server 端已正常關(guān)閉鞠绰,那好实昨,Client 也可以關(guān)閉連接了。
什么是MSL
MSL是Maximum Segment Lifetime英文的縮寫荒给,中文可以譯為“報(bào)文最大生存時(shí)間”,他是任何報(bào)文在網(wǎng)絡(luò)上存在的最長時(shí)間曙咽,超過這個(gè)時(shí)間報(bào)文將被丟棄挑辆。因?yàn)閠cp報(bào)文(segment)是ip數(shù)據(jù)報(bào)(datagram)的數(shù)據(jù)部分,具體稱謂請參見《數(shù)據(jù)在網(wǎng)絡(luò)各層中的稱呼》一文洒嗤,而ip頭中有一個(gè)TTL域魁亦,TTL是time to live的縮寫,中文可以譯為“生存時(shí)間”间唉,這個(gè)生存時(shí)間是由源主機(jī)設(shè)置初始值但不是存的具體時(shí)間,而是存儲了一個(gè)ip數(shù)據(jù)報(bào)可以經(jīng)過的最大路由數(shù)呈野,每經(jīng)過一個(gè)處理他的路由器此值就減1,當(dāng)此值為0則數(shù)據(jù)報(bào)將被丟棄军掂,同時(shí)發(fā)送ICMP報(bào)文通知源主機(jī)姆打。RFC 793中規(guī)定MSL為2分鐘肠虽,實(shí)際應(yīng)用中常用的是30秒,1分鐘和2分鐘等闲延。
2MSL即兩倍的MSL韩玩,TCP的TIME_WAIT狀態(tài)也稱為2MSL等待狀態(tài),當(dāng)TCP的一端發(fā)起主動關(guān)閉合愈,在發(fā)出最后一個(gè)ACK包后击狮,即第3次握手完成后發(fā)送了第四次握手的ACK包后就進(jìn)入了TIME_WAIT狀態(tài),必須在此狀態(tài)上停留兩倍的MSL時(shí)間彪蓬,等待2MSL時(shí)間主要目的是怕最后一個(gè)ACK包對方?jīng)]收到,那么對方在超時(shí)后將重發(fā)第三次握手的FIN包膘茎,主動關(guān)閉端接到重發(fā)的FIN包后可以再發(fā)一個(gè)ACK應(yīng)答包酷誓。在TIME_WAIT狀態(tài)時(shí)兩端的端口不能使用,要等到2MSL時(shí)間結(jié)束才可繼續(xù)使用棒拂。當(dāng)連接處于2MSL等待階段時(shí)任何遲到的報(bào)文段都將被丟棄娘扩。不過在實(shí)際應(yīng)用中可以通過設(shè)置SO_REUSEADDR選項(xiàng)達(dá)到不必等待2MSL時(shí)間結(jié)束再使用此端口壮锻。
TTL與MSL是有關(guān)系的但不是簡單的相等的關(guān)系猜绣,MSL要大于等于TTL敬特。
為什么要三次握手?
為什么要三次握手
TCP 建立連接伟阔,其實(shí)通過兩次握手就可以建立連接了辣之,為什么要三次呢皱炉?是不是多此一舉呢?
1合搅、《計(jì)算機(jī)網(wǎng)絡(luò)》中是這樣說的:
為了防止已失效的連接請求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯誤康铭。
在書中同時(shí)舉了一個(gè)例子赌髓,如下:
已失效的連接請求報(bào)文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個(gè)連接請求報(bào)文段并沒有丟失,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長時(shí)間的滯留了夷野,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server匿沛。本來這是一個(gè)早已失效的報(bào)文段。但server收到此失效的連接請求報(bào)文段后鳖孤,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請求。于是就向client發(fā)出確認(rèn)報(bào)文段苏揣,同意建立連接推姻。假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn)增炭,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求梅垄,因此不會理睬server的確認(rèn)输玷,也不會向server發(fā)送數(shù)據(jù)。但server卻以為新的運(yùn)輸連接已經(jīng)建立欲鹏,并一直等待client發(fā)來數(shù)據(jù)。這樣膘盖,server的很多資源就白白浪費(fèi)掉了尽狠。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況,client不會向server的確認(rèn)發(fā)出確認(rèn)掺冠。server由于收不到確認(rèn),就知道client并沒有要求建立連接德崭。”
2锌奴、網(wǎng)絡(luò)故障
比如憾股,現(xiàn)在網(wǎng)絡(luò)出現(xiàn)了故障,只能發(fā)請求數(shù)據(jù)包服球,而接收不到響應(yīng)數(shù)據(jù)包,那么只要發(fā)送一次請求往枣,服務(wù)器就建立請求,這樣肯定也是不對的圾另,網(wǎng)絡(luò)請求有來有回才能完成通訊雕沉。所以三次握手是必不可少的。
為什么要四次揮手呢
TCP協(xié)議是一種面向連接的饺著、可靠的、基于字節(jié)流的運(yùn)輸層通信協(xié)議幼衰。TCP是全雙工模式缀雳,這就意味著,當(dāng) Client 發(fā)出FIN報(bào)文段時(shí)识椰,只是表示 Client 已經(jīng)沒有數(shù)據(jù)要發(fā)送了深碱,Client 告訴 Server,它的數(shù)據(jù)已經(jīng)全部發(fā)送完畢了敷硅;但是功咒,這個(gè)時(shí)候 Client 還是可以接受來自 Server 的數(shù)據(jù)力奋;當(dāng) Server 返回ACK報(bào)文段時(shí)幽七,表示它已經(jīng)知道 Client 沒有數(shù)據(jù)發(fā)送了,但是 Server 還是可以發(fā)送數(shù)據(jù)到 Client 的猿挚;當(dāng) Server 也發(fā)送了FIN報(bào)文段時(shí)挪蹭,這個(gè)時(shí)候就表示 Server 也沒有數(shù)據(jù)要發(fā)送了,就會告訴 Client 梁厉,我也沒有數(shù)據(jù)要發(fā)送了踏兜,之后彼此就會愉快的中斷這次TCP連接碱妆。如果要正確的理解四次分手的原理昔驱,就需要了解四次分手過程中的狀態(tài)變化。