接上文
TCP 屬于傳輸層協(xié)議肺然,是面向有連接蔫缸,可靠的流協(xié)議。面對有連接這個特性狰挡,TCP 就有建立連接和斷開連接的過程捂龄。我們分別了解建立連接和斷開連接的流程以及當(dāng)中的一些疑問。
TCP 建立連接和斷開連接流程
首先我們來看下這張經(jīng)典的流程圖:
握手過程可以簡化為下面的四次交互:
1.Client 端首先發(fā)送一個 SYN 包加叁,告訴 Server 端我的初始序列號是 X倦沧;Client 端進(jìn)入了 SYN-SENT(同步已發(fā)送狀態(tài))狀態(tài)。
2.Server 端收到 SYN 包后回復(fù)給 Client 一個 ACK 確認(rèn)包它匕,告訴 Client 說我收到了展融;Server 端進(jìn)入了SYN-RCVD(同步收到)狀態(tài)。
3.接著 Server 端也需要告訴 Client 端自己的初始序列號豫柬,于是 Server 也發(fā)送一個 SYN 包告訴 Client 我的初始序列號是Y告希;
4.Client 端收到后,回復(fù) Server 一個 ACK 確認(rèn)包說我知道了烧给。之后 Client 和 Server 進(jìn)入ESTABLISHED(已建立連接)狀態(tài)燕偶。
重點(diǎn):Server 的 ACK 確認(rèn)包和接下來的 SYN 包合成一個SYN ACK包一起發(fā)送的,沒必要分別單獨(dú)發(fā)送础嫡,這樣子三次握手在進(jìn)行最少次交互的情況下完成了兩端的資源分配和初始化序列號的交換指么。
揮手過程詳解
TCP 的三次握手改成兩次握手可以嗎?
不可以榴鼎,一句話伯诬,主要防止已經(jīng)失效的連接請求報(bào)文突然又傳送到了服務(wù)器,從而產(chǎn)生錯誤巫财。
如果使用的是兩次握手建立連接盗似,假設(shè)有這樣一種場景,客戶端發(fā)送了第一個請求連接并且沒有丟失平项,只是因?yàn)樵诰W(wǎng)絡(luò)結(jié)點(diǎn)中滯留的時(shí)間太長了赫舒,由于TCP的客戶端遲遲沒有收到確認(rèn)報(bào)文,以為服務(wù)器沒有收到闽瓢,此時(shí)重新向服務(wù)器發(fā)送這條報(bào)文号阿,此后客戶端和服務(wù)器經(jīng)過兩次握手完成連接,傳輸數(shù)據(jù)鸳粉,然后關(guān)閉連接扔涧。此時(shí)此前滯留的那一次請求連接,網(wǎng)絡(luò)通暢了到達(dá)了服務(wù)器届谈,這個報(bào)文本該是失效的枯夜,但是,兩次握手的機(jī)制將會讓客戶端和服務(wù)器再次建立連接艰山,這將導(dǎo)致不必要的錯誤和資源的浪費(fèi)湖雹。
如果采用的是三次握手,就算是那一次失效的報(bào)文傳送過來了曙搬,服務(wù)端接受到了那條失效報(bào)文并且回復(fù)了確認(rèn)報(bào)文摔吏,但是客戶端不會再次發(fā)出確認(rèn)鸽嫂。由于服務(wù)器收不到確認(rèn),就知道客戶端并沒有請求連接征讲。
TCP 四次揮手能不能變成三次揮手呢据某?
答案是可能的。
TCP是全雙工通信诗箍,Client 在自己已經(jīng)不會在有新的數(shù)據(jù)要發(fā)送給 Server 后癣籽,可以發(fā)送 FIN 信號告知 Server,這邊已經(jīng)終止 Client 到對端 Server 那邊的數(shù)據(jù)傳輸滤祖。但是筷狼,這個時(shí)候?qū)Χ?Server 可以繼續(xù)往 Client 這邊發(fā)送數(shù)據(jù)包。于是匠童,兩端數(shù)據(jù)傳輸?shù)慕K止在時(shí)序上是獨(dú)立并且可能會相隔比較長的時(shí)間埂材,這個時(shí)候就必須最少需要2+2 = 4 次揮手來完全終止這個連接。但是汤求,如果Server在收到Client的FIN包后楞遏,在也沒數(shù)據(jù)需要發(fā)送給Client了,那么對Client的ACK包和Server自己的FIN包就可以合并成為一個包發(fā)送過去首昔,這樣四次揮手就可以變成三次了(似乎linux協(xié)議棧就是這樣實(shí)現(xiàn)的)寡喝。