TCP建立连接三次握手和释放连接四次握手
生活随笔
收集整理的這篇文章主要介紹了
TCP建立连接三次握手和释放连接四次握手
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
TCP建立連接三次握手和釋放連接四次握手
? ? 【尊重原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處】http://blog.csdn.net/guyuealian/article/details/52535294 ? ? ?在談及TCP建立連接和釋放連接過(guò)程,先來(lái)簡(jiǎn)單認(rèn)識(shí)一下TCP報(bào)文段首部格式的的幾個(gè)名詞(這里只是簡(jiǎn)單說(shuō)明,具體請(qǐng)查看相關(guān)教程) ? ??序列號(hào)seq:占4個(gè)字節(jié),用來(lái)標(biāo)記數(shù)據(jù)段的順序,TCP把連接中發(fā)送的所有數(shù)據(jù)字節(jié)都編上一個(gè)序號(hào),第一個(gè)字節(jié)的編號(hào)由本地隨機(jī)產(chǎn)生;給字節(jié)編上序號(hào)后,就給每一個(gè)報(bào)文段指派一個(gè)序號(hào);序列號(hào)seq就是這個(gè)報(bào)文段中的第一個(gè)字節(jié)的數(shù)據(jù)編號(hào)。
??? 確認(rèn)號(hào)ack:占4個(gè)字節(jié),期待收到對(duì)方下一個(gè)報(bào)文段的第一個(gè)數(shù)據(jù)字節(jié)的序號(hào);序列號(hào)表示報(bào)文段攜帶數(shù)據(jù)的第一個(gè)字節(jié)的編號(hào);而確認(rèn)號(hào)指的是期望接收到下一個(gè)字節(jié)的編號(hào);因此當(dāng)前報(bào)文段最后一個(gè)字節(jié)的編號(hào)+1即為確認(rèn)號(hào)。
? ??確認(rèn)ACK:占1位,僅當(dāng)ACK=1時(shí),確認(rèn)號(hào)字段才有效。ACK=0時(shí),確認(rèn)號(hào)無(wú)效
? ??同步SYN:連接建立時(shí)用于同步序號(hào)。當(dāng)SYN=1,ACK=0時(shí)表示:這是一個(gè)連接請(qǐng)求報(bào)文段。若同意連接,則在響應(yīng)報(bào)文段中使得SYN=1,ACK=1。因此,SYN=1表示這是一個(gè)連接請(qǐng)求,或連接接受報(bào)文。SYN這個(gè)標(biāo)志位只有在TCP建產(chǎn)連接時(shí)才會(huì)被置1,握手完成后SYN標(biāo)志位被置0。
? ??終止FIN:用來(lái)釋放一個(gè)連接。FIN=1表示:此報(bào)文段的發(fā)送方的數(shù)據(jù)已經(jīng)發(fā)送完畢,并要求釋放運(yùn)輸連接
? ??PS:ACK、SYN和FIN這些大寫的單詞表示標(biāo)志位,其值要么是1,要么是0;ack、seq小寫的單詞表示序號(hào)。 一、TCP建立連接三次握手 (1)、三次握手的過(guò)程 ? ?1)主機(jī)A向主機(jī)B發(fā)送TCP連接請(qǐng)求數(shù)據(jù)包,其中包含主機(jī)A的初始序列號(hào)seq(A)=x。(其中報(bào)文中同步標(biāo)志位SYN=1,ACK=0,表示這是一個(gè)TCP連接請(qǐng)求數(shù)據(jù)報(bào)文;序號(hào)seq=x,表明傳輸數(shù)據(jù)時(shí)的第一個(gè)數(shù)據(jù)字節(jié)的序號(hào)是x);
? ?2)主機(jī)B收到請(qǐng)求后,會(huì)發(fā)回連接確認(rèn)數(shù)據(jù)包。(其中確認(rèn)報(bào)文段中,標(biāo)識(shí)位SYN=1,ACK=1,表示這是一個(gè)TCP連接響應(yīng)數(shù)據(jù)報(bào)文,并含主機(jī)B的初始序列號(hào)seq(B)=y,以及主機(jī)B對(duì)主機(jī)A初始序列號(hào)的確認(rèn)號(hào)ack(B)=seq(A)+1=x+1)
? ?3)第三次,主機(jī)A收到主機(jī)B的確認(rèn)報(bào)文后,還需作出確認(rèn),即發(fā)送一個(gè)序列號(hào)seq(A)=x+1;確認(rèn)號(hào)為ack(A)=y+1的報(bào)文;
(2)為什么需要第三次握手? ? ? ?還要再發(fā)送一次確認(rèn)是為了,防止已失效的連接請(qǐng)求報(bào)文段突然又傳到了B,因而產(chǎn)生錯(cuò)誤。
? ? ?已失效的報(bào)文段:正常情況下:A發(fā)出連接請(qǐng)求,但因?yàn)閬G失了,故而不能收到B的確認(rèn)。于是A重新發(fā)出請(qǐng)求,然后收到確認(rèn),建立連接,數(shù)據(jù)傳輸完畢后,釋放連接,A發(fā)了2個(gè),一個(gè)丟掉,一個(gè)到達(dá),沒(méi)有“已失效的報(bào)文段”
? ? ?但是,某種情況下,A的第一個(gè)在某個(gè)節(jié)點(diǎn)滯留了,延誤到達(dá),本來(lái)這是一個(gè)早已失效的報(bào)文段,但是在A發(fā)送第二個(gè),并且得到B的回應(yīng),建立了連接以后,這個(gè)報(bào)文段竟然到達(dá)了,于是B就認(rèn)為,A又發(fā)送了一個(gè)新的請(qǐng)求,于是發(fā)送確認(rèn)報(bào)文段,同意建立連接,假若沒(méi)有三次的握手,那么這個(gè)連接就建立起來(lái)了(有一個(gè)請(qǐng)求和一個(gè)回應(yīng)),此時(shí),A收到B的確認(rèn),但A知道自己并沒(méi)有發(fā)送建立連接的請(qǐng)求,因?yàn)椴粫?huì)理睬B的這個(gè)確認(rèn),于是呢,A也不會(huì)發(fā)送任何數(shù)據(jù),而B(niǎo)呢卻以為新的連接建立了起來(lái),一直等待A發(fā)送數(shù)據(jù)給自己,此時(shí)B的資源就被白白浪費(fèi)了。但是采用三次握手的話,A就不發(fā)送確認(rèn),那么B由于收不到確認(rèn),也就知道并沒(méi)有要求建立連接。
? ? ?簡(jiǎn)而言之:第三次握手,主機(jī)A發(fā)送一次確認(rèn)是為了防止:如果客戶端遲遲沒(méi)有收到服務(wù)器返回的確認(rèn)報(bào)文,這時(shí)他會(huì)放棄連接,重新啟動(dòng)一條連接請(qǐng)求;但問(wèn)題是:服務(wù)器不知客戶端沒(méi)收到,所以他會(huì)收到兩個(gè)連接請(qǐng)求,白白浪費(fèi)了一條連接開(kāi)銷。
二、TCP釋放連接四次握手 (1)四次握手過(guò)程 假設(shè)主機(jī)A為客戶端,主機(jī)B為服務(wù)器,其釋放TCP連接的過(guò)程如下: ? ? 1) 關(guān)閉客戶端到服務(wù)器的連接:首先客戶端A發(fā)送一個(gè)FIN,用來(lái)關(guān)閉客戶到服務(wù)器的數(shù)據(jù)傳送,然后等待服務(wù)器的確認(rèn)。其中終止標(biāo)志位FIN=1,序列號(hào)seq=u ? 2) 服務(wù)器收到這個(gè)FIN,它發(fā)回一個(gè)ACK,確認(rèn)號(hào)ack為收到的序號(hào)加1。
? 3)?關(guān)閉服務(wù)器到客戶端的連接:也是發(fā)送一個(gè)FIN給客戶端。
? 4) 客戶段收到FIN后,并發(fā)回一個(gè)ACK報(bào)文確認(rèn),并將確認(rèn)序號(hào)seq設(shè)置為收到序號(hào)加1。
? ? ?首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。
? ? 主機(jī)A發(fā)送FIN后,進(jìn)入終止等待狀態(tài), 服務(wù)器B收到主機(jī)A連接釋放報(bào)文段后,就立即給主機(jī)A發(fā)送確認(rèn),然后服務(wù)器B就進(jìn)入close-wait狀態(tài),此時(shí)TCP服務(wù)器進(jìn)程就通知高層應(yīng)用進(jìn)程,因而從A到B的連接就釋放了。此時(shí)是“半關(guān)閉”狀態(tài)。即A不可以發(fā)送給B,但是B可以發(fā)送給A。
此時(shí),若B沒(méi)有數(shù)據(jù)報(bào)要發(fā)送給A了,其應(yīng)用進(jìn)程就通知TCP釋放連接,然后發(fā)送給A連接釋放報(bào)文段,并等待確認(rèn)。A發(fā)送確認(rèn)后,進(jìn)入time-wait,注意,此時(shí)TCP連接還沒(méi)有釋放掉,然后經(jīng)過(guò)時(shí)間等待計(jì)時(shí)器設(shè)置的2MSL后,A才進(jìn)入到close狀態(tài)。
(2)為什么要等待2MSL呢?
? ? MSL即Maximum Segment Lifetime,也就是最大報(bào)文生存時(shí)間,他是任何報(bào)文在網(wǎng)絡(luò)上存在的最長(zhǎng)時(shí)間,超過(guò)這個(gè)時(shí)間報(bào)文將被丟棄。引用《TCP/IP詳解》中的話:“它(MSL)是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長(zhǎng)時(shí)間”。RFC 793中規(guī)定MSL為2分鐘,實(shí)際應(yīng)用中常用的是30秒,1分鐘和2分鐘等。 ? ??TCP的TIME_WAIT狀態(tài)需要等待2MSL,當(dāng)TCP的一端發(fā)起主動(dòng)關(guān)閉,在發(fā)出最后一個(gè)ACK包后,即第3次握手完成后發(fā)送了第四次握手的ACK包后就進(jìn)入了TIME_WAIT狀態(tài),必須在此狀態(tài)上停留兩倍的MSL時(shí)間,等待2MSL時(shí)間主要目的是怕最后一個(gè)ACK包對(duì)方?jīng)]收到,那么對(duì)方在超時(shí)后將重發(fā)第三次握手的FIN包,主動(dòng)關(guān)閉端接到重發(fā)的FIN包后可以再發(fā)一個(gè)ACK應(yīng)答包。在TIME_WAIT狀態(tài)時(shí)兩端的端口不能使用,要等到2MSL時(shí)間結(jié)束才可繼續(xù)使用。當(dāng)連接處于2MSL等待階段時(shí)任何遲到的報(bào)文段都將被丟棄。不過(guò)在實(shí)際應(yīng)用中可以通過(guò)設(shè)置SO_REUSEADDR選項(xiàng)達(dá)到不必等待2MSL時(shí)間結(jié)束再使用此端口。 ? ? 概括原因如下: ? ? ①、為了保證A發(fā)送的最后一個(gè)ACK報(bào)文段能夠到達(dá)B。即最后這個(gè)確認(rèn)報(bào)文段很有可能丟失,那么B會(huì)超時(shí)重傳,然后A再一次確認(rèn),同時(shí)啟動(dòng)2MSL計(jì)時(shí)器,如此下去。如果沒(méi)有等待時(shí)間,發(fā)送完確認(rèn)報(bào)文段就立即釋放連接的話,B就無(wú)法重傳了(連接已被釋放,任何數(shù)據(jù)都不能出傳了),因而也就收不到確認(rèn),就無(wú)法按照步驟進(jìn)入CLOSE狀態(tài),即必須收到確認(rèn)才能close。
? ? ②、防止“已失效的連接請(qǐng)求報(bào)文段”出現(xiàn)在連接中。經(jīng)過(guò)2MSL,那些在這個(gè)連接持續(xù)的時(shí)間內(nèi),產(chǎn)生的所有報(bào)文段就可以都從網(wǎng)絡(luò)中消失。即在這個(gè)連接釋放的過(guò)程中會(huì)有一些無(wú)效的報(bào)文段滯留在樓閣結(jié)點(diǎn),但是呢,經(jīng)過(guò)2MSL這些無(wú)效報(bào)文段就肯定可以發(fā)送到目的地,不會(huì)滯留在網(wǎng)絡(luò)中。這樣的話,在下一個(gè)連接中就不會(huì)出現(xiàn)上一個(gè)連接遺留下來(lái)的請(qǐng)求報(bào)文段了。
可以看出:B結(jié)束TCP連接的時(shí)間比A早一點(diǎn),因?yàn)锽收到確認(rèn)就斷開(kāi)連接了,而A還得等待2MSL.
(3)為什么TCP釋放連接需要四次? ? ? ? TCP建立連接要進(jìn)行三次握手,而斷開(kāi)連接要進(jìn)行四次。這是由于TCP的半關(guān)閉造成的。因?yàn)門CP連接是全雙工的(即數(shù)據(jù)可在兩個(gè)方向上同時(shí)傳遞)所以進(jìn)行關(guān)閉時(shí)每個(gè)方向上都要單獨(dú)進(jìn)行關(guān)閉。這個(gè)單方向的關(guān)閉就叫半關(guān)閉。當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù),就發(fā)送一個(gè)FIN來(lái)向另一方通告將要終止這個(gè)方向的連接。 ??? ?注意: ? ? ?1)發(fā)送了FIN只是表示這端不能繼續(xù)發(fā)送數(shù)據(jù)(應(yīng)用層不能再調(diào)用send發(fā)送),但是還可以接收數(shù)據(jù)。收到一個(gè) FIN只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù),比如:如主機(jī)A收到主機(jī)B的FIN斷開(kāi)TCP連接請(qǐng)求,只是表示主機(jī)B已經(jīng)發(fā)送完數(shù)據(jù),主機(jī)A收到FIN后作出應(yīng)答,并終止這個(gè)方向的數(shù)據(jù)傳輸,此時(shí)處于半關(guān)閉狀態(tài)。但是主機(jī)A仍然可以發(fā)送數(shù)據(jù)的,只有當(dāng)主機(jī)A發(fā)送完數(shù)據(jù)并發(fā)送FIN給主機(jī)B時(shí),主機(jī)B才停止這個(gè)方向的數(shù)據(jù)傳輸,并關(guān)閉TCP連接。 ? ? ?2)在很多時(shí)候,TCP連接的斷開(kāi)都會(huì)由TCP層自動(dòng)進(jìn)行,例如你CTRL+C終止你的程序,TCP連接依然會(huì)正常關(guān)閉,你可以寫代碼試試。
來(lái)源:http://blog.csdn.net/guyuealian/article/details/52535294
總結(jié)
以上是生活随笔為你收集整理的TCP建立连接三次握手和释放连接四次握手的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PHP类实例教程(七):析构函数与PHP
- 下一篇: 查询银行房贷审批进度的方法 可以通过这