常見問題
1.詳細(xì)描述三次握手和四次揮手的過程。
2.三次握手可以變成兩次握手嗎?
3.簡述 TCP 連接和關(guān)閉的狀態(tài)轉(zhuǎn)移。
4.簡述TCP 四次揮手的 TIME_WAIT狀態(tài),以及為什么需要有這個(gè)狀態(tài)
重要的字段定義與作用
(1)序號(sequence number):seq序號,占32位,用來標(biāo)識從TCP源端向目的端發(fā)送的字節(jié)流,發(fā)起方發(fā)送數(shù)據(jù)時(shí)對此進(jìn)行標(biāo)記。
(2)確認(rèn)號(acknowledgement number):ack序號,占32位,只有ACK標(biāo)志位為1時(shí),確認(rèn)序號字段才有效,ack=seq+1。
(3)標(biāo)志位(Flags):共6個(gè),即URG、ACK、PSH、RST、SYN、FIN等。具體含義如下:
標(biāo)志位 | 含義 |
---|---|
URG | 緊急指針(urgent pointer)有效。 |
ACK | 確認(rèn)序號有效。(為了與確認(rèn)號ack區(qū)分開,我們用大寫表示) |
PSH | 接收方應(yīng)該盡快將這個(gè)報(bào)文交給應(yīng)用層。 |
RST | 重置連接。 |
SYN | 發(fā)起一個(gè)新連接。 |
FIN | 釋放一個(gè)連接。 |
這些字段有什么作用呢?
seq序號、ack序號:用于確認(rèn)數(shù)據(jù)是否準(zhǔn)確,是否正常通信。
標(biāo)志位:用于確認(rèn)/更改連接狀態(tài)
1. 三次握手
1.1 三次握手的詳細(xì)過程
1)第一次握手:建立連接時(shí),把SYN置1,客戶端向服務(wù)器發(fā)送SYN包(seq=x),請求建立連接,等待確認(rèn)。
2)第二次握手:服務(wù)端收到客戶端的SYN包,回一個(gè)ACK包(ack=x+1)確認(rèn)收到,同時(shí)發(fā)送一個(gè)SYN包(seq=y)給客戶端,也就是把SYN+ACK報(bào)文發(fā)送給客戶端。
3)第三次握手:客戶端收到服務(wù)器的SYN+ACK包后,再回一個(gè)ACK包(ack=y+1)告訴服務(wù)端已經(jīng)收到。
三次握手完成,成功建立連接,開始傳輸數(shù)據(jù)。通過以上三次連接,不管是服務(wù)端還是客戶端都彼此知道了,我既能給對方發(fā)送消息也能收到對方的消息,那么這個(gè)連接就能被安全的建立了。
1.2 三次握手的狀態(tài)變化:
一開始客戶端和服務(wù)器同時(shí)屬于CLOSED狀態(tài),表示沒有連接關(guān)系。
客戶端發(fā)送請求,客戶端打開發(fā)送(SYN-SENT)狀態(tài),同時(shí)服務(wù)器打開監(jiān)聽(Listen)狀態(tài);(第一次)
服務(wù)器在接收到客戶端的請求時(shí),服務(wù)器切換為回復(fù)(SYN-RCVD)狀態(tài);(第二次)
客戶端在接收到服務(wù)器的響應(yīng)時(shí),客戶端切換為穩(wěn)定連接(Established)狀態(tài)的同時(shí)發(fā)送第二次數(shù)據(jù)包。(第三次)
服務(wù)器在接收到客戶端的第二次數(shù)據(jù)時(shí),服務(wù)器切換為穩(wěn)定連接(Established)狀態(tài)。
雙方建立穩(wěn)定連接后,開始正常通信數(shù)據(jù)。
1.3 場景模擬
第一次握手:你能和我建立連接嗎,可以接受到我的數(shù)據(jù)嗎。
? SYN = 1 ,seq = x
第二次握手:可以建立連接,我接受到你的請求了,能接受到我的數(shù)據(jù)嗎,你的數(shù)據(jù)是這個(gè)嗎
? SYN = 1 ,ACK = 1 ,seq = y ,ack = x + 1
第三次握手:我已經(jīng)收到你的回復(fù),這是我的數(shù)據(jù),這是你的數(shù)據(jù)(用于再次核對)
? ACK = 1 ,seq = x + 1 ,ack = y + 1
建立連接成功。
2. 四次揮手
2.1 四次揮手的詳細(xì)過程
1)客戶端發(fā)送FIN包(FIN=1)給服務(wù)端,告訴它自己的數(shù)據(jù)已經(jīng)發(fā)送完畢,請求終止連接,此時(shí)客戶端不發(fā)送數(shù)據(jù),但還能接收數(shù)據(jù)
2)服務(wù)端收到FIN包,回一個(gè)ACK包給客戶端告訴它已經(jīng)收到包了,此時(shí)還沒有斷開socket連接,而是等待剩下的數(shù)據(jù)傳輸完畢
3)服務(wù)端等待數(shù)據(jù)傳輸完畢后,向客戶端發(fā)送FIN包,表明可以斷開連接
4)客戶端收到后,回一個(gè)ACK包表明確認(rèn)收到,等待一段時(shí)間,確保服務(wù)端不再有數(shù)據(jù)發(fā)過來,然后徹底斷開連接
2.2 四次揮手的狀態(tài)變化
一開始客戶端和服務(wù)器同時(shí)屬于ESTABLISHED狀態(tài),表示可以互相發(fā)送數(shù)據(jù)。
(1)第一次揮手:客戶端發(fā)送終止連接的請求后處于FIN_WAIT_1狀態(tài),這時(shí)的客戶端只能接受數(shù)據(jù)
(2)服務(wù)端(被動關(guān)閉的一方)收到終止連接請求后,發(fā)出一個(gè)ACK包代表服務(wù)端已經(jīng)收到終止請求,然后進(jìn)入CLOSE_WAIT狀態(tài),這時(shí)客戶端進(jìn)入FIN_WAIT_2狀態(tài)
(3)然后服務(wù)端要先把還沒發(fā)送完的數(shù)據(jù)發(fā)送給客戶端,數(shù)據(jù)傳輸完畢后,向客戶端發(fā)送FIN包,表明可以斷開連接之后進(jìn)入LAST_ACK
(4)客戶端收到FIN包后再回一個(gè)ACK包表明確認(rèn)收到,進(jìn)入IME_WAIT狀態(tài)(等待一段時(shí)間,確保服務(wù)端不再有數(shù)據(jù)發(fā)過來,然后徹底斷開連接),也就是等待后客戶端和服務(wù)端一起進(jìn)入CLOSED狀態(tài)。
2.3 說說 TCP 2次握手行不行?為什么要3次
為了實(shí)現(xiàn)可靠數(shù)據(jù)傳輸, TCP 協(xié)議的通信雙方, 都必須維護(hù)一個(gè)序列號, 以標(biāo)識發(fā)送出去的數(shù)據(jù)包中, 哪些是已經(jīng)被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 并確認(rèn)對方已經(jīng)收到了序列號起始值的必經(jīng)步驟
如果只是兩次握手, 至多只有連接發(fā)起方的起始序列號能被確認(rèn), 另一方選擇的序列號則得不到確認(rèn)
3. 簡述 TCP 連接 和 關(guān)閉的狀態(tài)轉(zhuǎn)移
上半部分是TCP三路握手過程的狀態(tài)變遷,下半部分是TCP四次揮手過程的狀態(tài)變遷。
1.CLOSED:起始點(diǎn),在超時(shí)或者連接關(guān)閉時(shí)候進(jìn)入此狀態(tài),這并不是一個(gè)真正的狀態(tài),而是這個(gè)狀態(tài)圖的假想起點(diǎn)和終點(diǎn)。
2.LISTEN:服務(wù)器端等待連接的狀態(tài)。服務(wù)器經(jīng)過 socket,bind,listen 函數(shù)之后進(jìn)入此狀態(tài),開始監(jiān)聽客戶端發(fā)過來的連接請求。此稱為應(yīng)用程序被動打開(等到客戶端連接請求)。
3.SYN_SENT:第一次握手發(fā)生階段,客戶端發(fā)起連接。客戶端調(diào)用 connect,發(fā)送 SYN 給服務(wù)器端,然后進(jìn)入 SYN_SENT 狀態(tài),等待服務(wù)器端確認(rèn)(三次握手中的第二個(gè)報(bào)文)。如果服務(wù)器端不能連接,則直接進(jìn)入CLOSED狀態(tài)。
4.SYN_RCVD:第二次握手發(fā)生階段,跟 3 對應(yīng),這里是服務(wù)器端接收到了客戶端的 SYN,此時(shí)服務(wù)器由 LISTEN 進(jìn)入 SYN_RCVD狀態(tài),同時(shí)服務(wù)器端回應(yīng)一個(gè) ACK,然后再發(fā)送一個(gè) SYN 即 SYN+ACK 給客戶端。狀態(tài)圖中還描繪了這樣一種情況,當(dāng)客戶端在發(fā)送 SYN 的同時(shí)也收到服務(wù)器端的 SYN請求,即兩個(gè)同時(shí)發(fā)起連接請求,那么客戶端就會從 SYN_SENT 轉(zhuǎn)換到 SYN_REVD 狀態(tài)。
5.ESTABLISHED:第三次握手發(fā)生階段,客戶端接收到服務(wù)器端的 ACK 包(ACK,SYN)之后,也會發(fā)送一個(gè) ACK 確認(rèn)包,客戶端進(jìn)入 ESTABLISHED 狀態(tài),表明客戶端這邊已經(jīng)準(zhǔn)備好,但TCP 需要兩端都準(zhǔn)備好才可以進(jìn)行數(shù)據(jù)傳輸。服務(wù)器端收到客戶端的 ACK 之后會從 SYN_RCVD 狀態(tài)轉(zhuǎn)移到 ESTABLISHED 狀態(tài),表明服務(wù)器端也準(zhǔn)備好進(jìn)行數(shù)據(jù)傳輸了。這樣客戶端和服務(wù)器端都是 ESTABLISHED 狀態(tài),就可以進(jìn)行后面的數(shù)據(jù)傳輸了。所以 ESTABLISHED 也可以說是一個(gè)數(shù)據(jù)傳送狀態(tài)。
下面看看TCP四次揮手過程的狀態(tài)變遷。
1.FIN_WAIT_1:第一次揮手。主動關(guān)閉的一方(執(zhí)行主動關(guān)閉的一方既可以是客戶端,也可以是服務(wù)器端,這里以客戶端執(zhí)行主動關(guān)閉為例)終止連接時(shí),發(fā)送 FIN 給對方,然后等待對方返回 ACK 。調(diào)用 close() 第一次揮手就進(jìn)入此狀態(tài)。
2.CLOSE_WAIT:接收到FIN 之后,被動關(guān)閉的一方進(jìn)入此狀態(tài)。具體動作是接收到 FIN,同時(shí)發(fā)送 ACK。之所以叫 CLOSE_WAIT 可以理解為被動關(guān)閉的一方此時(shí)正在等待上層應(yīng)用程序發(fā)出關(guān)閉連接指令。TCP關(guān)閉是全雙工過程,這里客戶端執(zhí)行了主動關(guān)閉,被動方服務(wù)器端接收到FIN 后也需要調(diào)用 close 關(guān)閉,這個(gè) CLOSE_WAIT 就是處于這個(gè)狀態(tài),等待發(fā)送 FIN,發(fā)送了FIN 則進(jìn)入 LAST_ACK 狀態(tài)。
3.FIN_WAIT_2:主動端(這里是客戶端)先執(zhí)行主動關(guān)閉發(fā)送FIN,然后接收到被動方返回的 ACK 后進(jìn)入此狀態(tài)。
4.LAST_ACK:被動方(服務(wù)器端)發(fā)起關(guān)閉請求,由狀態(tài)2 進(jìn)入此狀態(tài),具體動作是發(fā)送 FIN給對方,同時(shí)在接收到ACK 時(shí)進(jìn)入CLOSED狀態(tài)。
5.CLOSING:兩邊同時(shí)發(fā)起關(guān)閉請求時(shí)(即主動方發(fā)送FIN,等待被動方返回ACK,同時(shí)被動方也發(fā)送了FIN,主動方接收到了FIN之后,發(fā)送ACK給被動方),主動方會由FIN_WAIT_1 進(jìn)入此狀態(tài),等待被動方返回ACK。
6.TIME_WAIT:從狀態(tài)變遷圖會看到,四次揮手操作最后都會經(jīng)過這樣一個(gè)狀態(tài)然后進(jìn)入CLOSED狀態(tài)。
4.簡述 TCP 四次揮手的 TIME_WAIT狀態(tài),為什么需要有這個(gè)狀態(tài)
TIME_WAIT狀態(tài)也稱為2MSL等待狀態(tài)。每個(gè)具體TCP實(shí)現(xiàn)必須選擇一個(gè)報(bào)文段最大生存時(shí)間MSL(Maximum Segment Lifetime),它是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長時(shí)間。
對一個(gè)具體實(shí)現(xiàn)所給定的MSL值,處理的原則是:當(dāng)TCP執(zhí)行一個(gè)主動關(guān)閉,并發(fā)回最后一個(gè)ACK,該連接必須在TIME_WAIT狀態(tài)停留的時(shí)間為2倍的MSL。這樣可讓TCP再次發(fā)送最后的ACK以防這個(gè)ACK丟失(另一端超時(shí)并重發(fā)最后的FIN)。
理論上,四次揮手的四個(gè)報(bào)文都發(fā)送完畢,就可以直接進(jìn)入CLOSE狀態(tài)了,但是可能網(wǎng)絡(luò)是不可靠的,有可能最后一次揮手的ACK,也就是最后一個(gè)ACK會丟失。所以TIME_WAIT狀態(tài)就是用來重發(fā)可能丟失的ACK報(bào)文。
5. 簡述什么是 MSL,為什么客戶端連接要等待2MSL的時(shí)間才能完全關(guān)閉
MSL是 Maximum Segment Lifetime 的英文縮寫,可譯為“ 最長報(bào)文段壽命 ”,它是任何報(bào)文在網(wǎng)絡(luò)上存在的最長時(shí)間,超過這個(gè)時(shí)間報(bào)文將被丟棄。文章來源:http://www.zghlxwxcb.cn/news/detail-523938.html
為了保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文段能夠到達(dá)服務(wù)器。因?yàn)檫@個(gè)ACK有可能丟失,從而導(dǎo)致處在LAST-ACK狀態(tài)的服務(wù)器收不到對FIN-ACK的確認(rèn)報(bào)文。服務(wù)器會超時(shí)重傳這個(gè)FIN-ACK,接著客戶端再重傳一次確認(rèn),重新啟動時(shí)間等待計(jì)時(shí)器。最后客戶端和服務(wù)器都能正常的關(guān)閉。假設(shè)客戶端不等待2MSL,而是在發(fā)送完ACK之后直接釋放關(guān)閉,一但這個(gè)ACK丟失的話,服務(wù)器就無法正常的進(jìn)入關(guān)閉連接狀態(tài)。文章來源地址http://www.zghlxwxcb.cn/news/detail-523938.html
- 兩個(gè)理由:
1.保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文段能夠到達(dá)服務(wù)端。
這個(gè)ACK報(bào)文段有可能丟失,使得處于LAST-ACK狀態(tài)的B收不到對已發(fā)送的FIN+ACK報(bào)文段的確認(rèn),服務(wù)端超時(shí)重傳FIN+ACK報(bào)文段,而客戶端能在2MSL時(shí)間內(nèi)收到這個(gè)重傳的FIN+ACK報(bào)文段,接著客戶端重傳一次確認(rèn),重新啟動2MSL計(jì)時(shí)器,最后客戶端和服務(wù)端都進(jìn)入到CLOSED狀態(tài),若客戶端在TIME-WAIT狀態(tài)不等待一段時(shí)間,而是發(fā)送完ACK報(bào)文段后立即釋放連接,則無法收到服務(wù)端重傳的FIN+ACK報(bào)文段,所以不會再發(fā)送一次確認(rèn)報(bào)文段,則服務(wù)端無法正常進(jìn)入到CLOSED狀態(tài)。
2.防止“已失效的連接請求報(bào)文段”出現(xiàn)在本連接中。
客戶端在發(fā)送完最后一個(gè)ACK報(bào)文段后,再經(jīng)過2MSL,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失,使下一個(gè)新的連接中不會出現(xiàn)這種舊的連接請求報(bào)文段。
到了這里,關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)面經(jīng)之TCP三次握手和四次揮手的詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!