第五章 运输层(UDP和TCP三次握手,四次挥手分析)
序言
? 通過(guò)這章,可以知道其實(shí)三次握手和四次揮手其實(shí)真的好簡(jiǎn)單,通過(guò)這章的學(xué)習(xí),我相信你也會(huì)同樣的認(rèn)為,以后在也不需要聽(tīng)到別人問(wèn)三次握手的過(guò)程而自己一臉懵逼了,覺(jué)得人家好屌,其實(shí)也就是他懂你不懂,僅此而已,不懂就去學(xué)。學(xué)了你就會(huì)覺(jué)得其實(shí)也就那樣,沒(méi)有什么厲害的,這讓我回想以前剛學(xué)習(xí)編程的時(shí)候,那時(shí)候剛學(xué)C,別人就說(shuō)會(huì)寫(xiě)java的helloworld,真TM覺(jué)得屌啊,我連helloworld是什么度不知道。一直羨慕人家,怎么這么厲害,然后自己心里很虛,自己這么菜啊,其實(shí)不然,不懂的就去學(xué)習(xí),學(xué)懂了你也就沒(méi)覺(jué)得什么了不起,所以說(shuō),不與他人相比,但求超越自己。希望能幫到現(xiàn)在迷茫的同學(xué)。
?
重點(diǎn)在TCP的三次握手和四次揮手,還有TCP的一些特性。
--WH
?
一、運(yùn)輸層概述
這一層的功能也挺簡(jiǎn)單的,運(yùn)輸層提供應(yīng)用層提供端到端通信服務(wù),通俗的講,兩個(gè)主機(jī)通訊,也就是應(yīng)用層上的進(jìn)程之間的通信,也就是轉(zhuǎn)換為進(jìn)程和進(jìn)程之間的通信了,我們之前學(xué)到網(wǎng)絡(luò)層,IP協(xié)議能將分組準(zhǔn)確的發(fā)送到目的主機(jī),但是停留在網(wǎng)絡(luò)層,并不知道要怎么交給我們的主機(jī)應(yīng)用進(jìn)程,通過(guò)前面的學(xué)習(xí),我們學(xué)習(xí)有mac地址,通過(guò)mac地址能找到同一個(gè)網(wǎng)絡(luò)下主機(jī),有IP地址,通過(guò)ip地址能找到不同網(wǎng)絡(luò)下的網(wǎng)絡(luò),結(jié)合mac地址就能找到對(duì)應(yīng)主機(jī),那么怎么找到主機(jī)應(yīng)用進(jìn)程呢,肯定也有一個(gè)東西來(lái)標(biāo)識(shí)它,那就是我們常說(shuō)的端口了。
端口,占有16位,其大小也就有65536個(gè),是從0~65535.也就是一臺(tái)計(jì)算機(jī)有65535個(gè)端口,主機(jī)之間的通訊,也就是應(yīng)用進(jìn)程之間的通訊,度要依靠端口,一個(gè)進(jìn)程對(duì)應(yīng)一個(gè)端口,進(jìn)程A和進(jìn)程B通信,進(jìn)程A分到的端口為60000,進(jìn)程B分到的端口為60001,進(jìn)程A通過(guò)端口60000發(fā)送數(shù)據(jù)給進(jìn)程B,就知道要交給60001端口,也就到了進(jìn)程B中 ,這樣就達(dá)到了通信的目的。
熟知端口、登記端口、客戶端端口
熟知端口:0-1023, 也就是一些固定的端口號(hào),比如http使用的80端口,意思就是在訪問(wèn)網(wǎng)址時(shí),我們?cè)L問(wèn)服務(wù)器的端口就是80,然后服務(wù)器那邊傳網(wǎng)頁(yè)的數(shù)據(jù)給我們。
登記端口:1024-49151,比如微軟開(kāi)發(fā)了一個(gè)系統(tǒng)應(yīng)用,該應(yīng)用在通訊或使用時(shí),需要使用到xxx端口,那么就要去登記一下這個(gè)端口,以免有別人公司的應(yīng)用使用同一個(gè)端口號(hào),例如,windows系統(tǒng)中的3389端口,就是用來(lái)實(shí)現(xiàn)遠(yuǎn)程連接的,就固定了這臺(tái)計(jì)算機(jī)如果要使用遠(yuǎn)程連接服務(wù),就打開(kāi)3389端口,別人就能使用遠(yuǎn)程連接連你了,默認(rèn)是不打開(kāi)的。
客戶端端口:49152-65535,一般我們使用某個(gè)軟件,比如QQ,等其他服務(wù),隨機(jī)拿這個(gè)范圍內(nèi)的端口,而不是去拿前面哪些固定的,拿到等通訊結(jié)束后,就會(huì)釋放該端口。
?
知道了端口是什么?運(yùn)輸層具體做了什么事情呢?運(yùn)輸層就是將兩個(gè)端口連起來(lái)通信的介質(zhì),不然光知道兩個(gè)端口有什么用,怎么通信的,還是要靠運(yùn)輸層來(lái)做這個(gè)事情,其中重要的就是靠?jī)蓚€(gè)協(xié)議,UDP和TCP協(xié)議。下面就來(lái)講講UDP和TCP協(xié)議的具體內(nèi)容。
?
二、UDP協(xié)議
UDP:User Datagram Protocol 用戶數(shù)據(jù)報(bào)協(xié)議。
無(wú)連接、不可靠
無(wú)連接:意思就是在通訊之前不需要建立連接,直接傳輸數(shù)據(jù)。
不可靠:是將數(shù)據(jù)報(bào)的分組從一臺(tái)主機(jī)發(fā)送到另一臺(tái)主機(jī),但并不保證數(shù)據(jù)報(bào)能夠到達(dá)另一端,任何必須的可靠性都由應(yīng)用程序提供。在 UDP 情況下,雖然可以確保發(fā)送消息的大小,卻不能保證消息一定會(huì)達(dá)到目的端。沒(méi)有超時(shí)和重傳功能,當(dāng) UDP 數(shù)據(jù)封裝到 IP 數(shù)據(jù)報(bào)傳輸時(shí),如果丟失,會(huì)發(fā)送一個(gè) ICMP 差錯(cuò)報(bào)文給源主機(jī)。即使出現(xiàn)網(wǎng)絡(luò)阻塞情況,UDP 也無(wú)法進(jìn)行流量控制。此外,傳輸途中即使出現(xiàn)丟包,UDP 也不負(fù)責(zé)重發(fā),甚至當(dāng)出現(xiàn)包的到達(dá)順序雜亂也沒(méi)有糾正的功能
UDP的首部格式
先看UDP首部,
源端口號(hào):占16位,源主機(jī)的應(yīng)用進(jìn)程所使用的端口號(hào)
目標(biāo)端口號(hào):占16位,目標(biāo)主機(jī)的應(yīng)用進(jìn)程所使用的端口號(hào),也就是我們需要通信的目標(biāo)進(jìn)程
UDP報(bào)長(zhǎng)度:UDP用戶數(shù)據(jù)報(bào)的長(zhǎng)度,數(shù)據(jù)部分+UDP首部之和為UDP報(bào)長(zhǎng)度。
檢驗(yàn)和:檢驗(yàn)和是為了提供可靠的 UDP 首部和數(shù)據(jù)而設(shè)計(jì),這里不要和上面的不可靠傳輸搞混淆了,這里提供可靠的UDP首部,是因?yàn)橐粋€(gè)進(jìn)程可能接受多個(gè)進(jìn)程過(guò)來(lái)的報(bào)文,那么如何區(qū)分他們呢,就是通過(guò)5個(gè)東西來(lái)進(jìn)行區(qū)分的, “源 IP 地址”、“目的 IP 地址”、“協(xié)議號(hào)”、“源端口號(hào)”、“目標(biāo)端口號(hào)”的,這個(gè)檢測(cè)可靠,是檢測(cè)接受哪個(gè)正確的報(bào)文,也就是說(shuō)是哪個(gè)報(bào)文要進(jìn)這個(gè)端口,那個(gè)不可靠,說(shuō)的是這個(gè)報(bào)文可能丟失,可能其中數(shù)據(jù)損壞了我們不關(guān)心,但是這些的前提是,你得傳輸?shù)秸_的目的地去,不然亂出亂發(fā)數(shù)據(jù)報(bào),豈不是亂套了。
UDP偽首部
就是拿到IP層的一些數(shù)據(jù),因?yàn)橐M(jìn)行檢驗(yàn)和,就必須要有這些數(shù)據(jù)。其中檢驗(yàn)的算法跟IP層中檢驗(yàn)首部的辦法是一樣的。
?
分析
?
一個(gè)目標(biāo)進(jìn)程中,其中的報(bào)文,目標(biāo)端口,目標(biāo)ip地址肯定都市一樣的,但是源IP地址和源端口就可能不一樣,這就說(shuō)明了不同源而同一目的地的報(bào)文會(huì)定位到同一隊(duì)列。這跟接下來(lái)我們要討論的TCP不一樣,因?yàn)閁DP是無(wú)連接的,大家度是用這一條通道,所以其隊(duì)列中就會(huì)出現(xiàn)上面所說(shuō)的這樣的情況。
使用UDP協(xié)議的例子
1、應(yīng)用層協(xié)議中DNS,也就是根據(jù)域名解析ip地址的一個(gè)協(xié)議,他使用的就是UDP
2、DHCP,這個(gè)是給各電腦分配ip地址的協(xié)議,其中用的也是UDP協(xié)議
3、IGMP,我們說(shuō)的多播,也就是使用的UDP,在多媒體教師,老師拿筆記本講課,我們?cè)谙旅嫱ㄟ^(guò)各自的電腦看到老師的畫(huà)面,這就是通過(guò)UDP傳輸數(shù)據(jù),所以會(huì)出現(xiàn)有的同學(xué)卡,有的同學(xué)很流暢,就是因?yàn)槠洳豢煽總鬏?#xff0c;但是卡一下,對(duì)接下來(lái)的觀看并沒(méi)有什么映像
還有挺多的度是用到UDP協(xié)議。
?
?
三、TCP協(xié)議
TCP協(xié)議是面向連接的、可靠傳輸、有流量控制,擁塞控制,面向字節(jié)流傳輸?shù)群芏鄡?yōu)點(diǎn)的協(xié)議。其最終功能和UDP一樣,在端和端之間進(jìn)行通信,但是和UDP的區(qū)別還是很大的。
TCP報(bào)文的結(jié)構(gòu)
1、源端口號(hào)
2、目標(biāo)端口號(hào)
3、序列號(hào):因?yàn)樵赥CP是面向字節(jié)流的,他會(huì)將報(bào)文度分成一個(gè)個(gè)字節(jié),給每個(gè)字節(jié)進(jìn)行序號(hào)編寫(xiě),比如一個(gè)報(bào)文有900個(gè)字節(jié)組成,那么就會(huì)編成1-900個(gè)序號(hào),然后分幾部分來(lái)進(jìn)行傳輸,比如第一次傳,序列號(hào)就是1,傳了50個(gè)字節(jié), 那么第二次傳,序列號(hào)就為51,所以序列號(hào)就是傳輸?shù)臄?shù)據(jù)的第一個(gè)字節(jié)相對(duì)所有的字節(jié)的位置。
4、確認(rèn)應(yīng)答:如剛說(shuō)的例子,第一次傳了50個(gè)字節(jié)給對(duì)方,對(duì)方也會(huì)回應(yīng)你,其中帶有確認(rèn)應(yīng)答,就是告訴你下一次要傳第51個(gè)字節(jié)來(lái)了,所以這個(gè)確認(rèn)應(yīng)答就是告訴對(duì)方要傳第多少個(gè)字節(jié)了
5、首部長(zhǎng)度:就是首部的長(zhǎng)度,
6、保留:給以后有需要在用,這個(gè)保留的位置放的東西是跟控制位類似的
7、控制位:目前有的控制位為6個(gè)
URG:緊急,當(dāng)URG為1時(shí),表名緊急指針字段有效,標(biāo)識(shí)該報(bào)文是一個(gè)緊急報(bào)文,傳送到目標(biāo)主機(jī)后,不用排隊(duì),應(yīng)該讓該報(bào)文盡量往下排,讓其早點(diǎn)讓?xiě)?yīng)用程序給接受。
ACK:確認(rèn),當(dāng)ACK為1時(shí),確認(rèn)序號(hào)才有效。當(dāng)ACK為0時(shí),確認(rèn)序號(hào)沒(méi)用
PSH:推送,當(dāng)為1時(shí),當(dāng)遇到此報(bào)文時(shí),會(huì)減少數(shù)據(jù)向上交付,本來(lái)想應(yīng)用進(jìn)程交付數(shù)據(jù)是要等到一定的緩存大小才發(fā)送的,但是遇到它,就不用在等足夠多的數(shù)據(jù)才向上交付,而是讓?xiě)?yīng)用進(jìn)程早點(diǎn)拿到此報(bào)文,這個(gè)要和緊急分清楚,緊急是插隊(duì),但是提交緩存大小的數(shù)據(jù)不變,這個(gè)推送就要排隊(duì),但是遇到他的時(shí)候,會(huì)減少交付的緩存數(shù)據(jù),提前交付。
RST:復(fù)位,報(bào)文遇到很嚴(yán)重的差錯(cuò)時(shí),比如TCP連接出錯(cuò)等,會(huì)將RST置為1,然后釋放連接,全部重新來(lái)過(guò)。
SYN:同步,在進(jìn)行連接的時(shí)候,也就是三次握手時(shí)用得到,下面會(huì)具體講到,配合ACK一起使用
FIN:終止,在釋放連接時(shí),也就是四次揮手時(shí)用的。
8、窗口:指發(fā)送報(bào)文段一方的接受窗口大小,用來(lái)控制對(duì)方發(fā)送的數(shù)據(jù)量(從確認(rèn)號(hào)開(kāi)始,允許對(duì)方發(fā)送的數(shù)據(jù)量)。也就是后面需要講的滑動(dòng)窗口的窗口大小
9、檢驗(yàn)和:檢驗(yàn)首部和數(shù)據(jù)這兩部分,和UDP一樣,需要拿到偽首部中的數(shù)據(jù)來(lái)幫助檢測(cè)
10、選項(xiàng):長(zhǎng)度可變,介紹一種選項(xiàng),最大報(bào)文段長(zhǎng)度,MSS。 能夠告訴對(duì)方TCP,我的緩存能接受報(bào)文段的數(shù)據(jù)字段的最大長(zhǎng)度是MSS個(gè)字節(jié)。如果沒(méi)有使用選項(xiàng),那么首部固定是20個(gè)字節(jié)。
11、填充:就是為了讓其成為整數(shù)個(gè)字節(jié)
?
?
面向連接
(三次握手):在通信之前,會(huì)先通過(guò)三次握手的機(jī)制來(lái)確認(rèn)兩端口之間的連接是否可用。而UDP不需要確認(rèn)是否可用,直接傳。
三次握手機(jī)制。
一開(kāi)始客戶端和服務(wù)端都市關(guān)閉狀態(tài),但是在某個(gè)時(shí)刻,客戶端需要和服務(wù)端進(jìn)行通信,此時(shí)雙方都會(huì)各自準(zhǔn)備好端口,服務(wù)器段的端口會(huì)處于監(jiān)聽(tīng)狀態(tài),等待客戶端的連接??蛻舳丝蓵?huì)知道自己的端口號(hào),和目的進(jìn)程的端口號(hào),這樣才能發(fā)起請(qǐng)求。
第一次握手:客戶端想與服務(wù)器進(jìn)行連接了,所以狀態(tài)變?yōu)橹鲃?dòng)打開(kāi),同時(shí)發(fā)送一個(gè)連接請(qǐng)求報(bào)文給服務(wù)器段SYN=1,并且會(huì)攜帶x個(gè)字節(jié)過(guò)去。發(fā)送完請(qǐng)求連接報(bào)文后,客戶端的狀態(tài)就變?yōu)榱薙YN_SENT,可以說(shuō)這個(gè)狀態(tài)是等待發(fā)送確認(rèn)(為了發(fā)送第三次握手時(shí)的確認(rèn)包)
第二次握手:服務(wù)端接收到連接請(qǐng)求報(bào)文后,從LSTTEN狀態(tài)變?yōu)楸粍?dòng)打開(kāi)狀態(tài),然后給客戶端返回一個(gè)報(bào)文。這個(gè)報(bào)文有兩層意思,一是確認(rèn)報(bào)文,而可以達(dá)到告訴客戶端,我也打開(kāi)連接了。發(fā)完后,變?yōu)镾YN_RCVD狀態(tài)(也可以說(shuō)是等待接受確認(rèn)狀態(tài),接受客戶端發(fā)過(guò)來(lái)的確認(rèn)包)
第三次握手:客戶端得到服務(wù)器端的確認(rèn)和知道服務(wù)器端也已經(jīng)準(zhǔn)備好了連接后,還會(huì)發(fā)一個(gè)確認(rèn)報(bào)文到服務(wù)器端,告訴服務(wù)器端,我接到了你發(fā)送的報(bào)文,接下來(lái)就讓我們兩個(gè)進(jìn)行連接了。客戶端發(fā)送完確認(rèn)報(bào)文后,進(jìn)入ESTABLISHED,而服務(wù)器接到了,也變?yōu)镋STABLISHED
進(jìn)入到ESTABLISHED狀態(tài)后,連接就已經(jīng)完成了,可以進(jìn)行通信了。
問(wèn)題:為什么需要第三次握手,有前面兩次不就已經(jīng)可以了嗎?
假設(shè)沒(méi)有第三次握手,客戶端發(fā)送一個(gè)連接請(qǐng)求報(bào)文過(guò)去,但是因?yàn)榫W(wǎng)絡(luò)延遲,在等待了一個(gè)超時(shí)時(shí)間后,客戶端就會(huì)在重新發(fā)一個(gè)請(qǐng)求連接報(bào)文過(guò)去,然后正常的進(jìn)行,服務(wù)器端發(fā)回一個(gè)確認(rèn)連接報(bào)文,然后就開(kāi)始通訊,通訊結(jié)束后,那個(gè)第一次因?yàn)榫W(wǎng)絡(luò)延遲的請(qǐng)求連接報(bào)文到了服務(wù)器端,服務(wù)器端不知道這個(gè)報(bào)文已經(jīng)失效,也發(fā)回了一個(gè)確認(rèn)連接報(bào)文,客戶端接收后,發(fā)現(xiàn)自己并沒(méi)有發(fā)送連接請(qǐng)求(因?yàn)槌瑫r(shí)了,所以就認(rèn)為自己沒(méi)有發(fā)),所以對(duì)這個(gè)確認(rèn)連接請(qǐng)求就什么也不做,但是此時(shí)客戶端不這么認(rèn)為,他認(rèn)為i連接已經(jīng)建立了,就一直打開(kāi)著等待客戶端傳數(shù)據(jù)過(guò)來(lái),這就造成了極大的浪費(fèi)。如果有了第三次握手,那么客戶端就可以通知服務(wù)器了。所以第三次握手也很重要。
?
同時(shí)打開(kāi)連接請(qǐng)求
正常情況下,通信一方請(qǐng)求建立連接,另一方響應(yīng)該請(qǐng)求,但是如果出現(xiàn),通信雙方同時(shí)請(qǐng)求建立連接時(shí),則連接建立過(guò)程并不是三次握手過(guò)程,而且這種情況的連接也只有一條,并不會(huì)建立兩條連接。同時(shí)打開(kāi)連接時(shí),兩邊幾乎同時(shí)發(fā)送 SYN,并進(jìn)入 SYN_SENT 狀態(tài),當(dāng)每一端收到 SYN 時(shí),狀態(tài)變?yōu)?SYN_RCVD,同時(shí)雙方都再發(fā) SYN 和 ACK 作為對(duì)收到的 SYN 進(jìn)行確認(rèn)應(yīng)答。當(dāng)雙方都收到 SYN 及相應(yīng)的 ACK 時(shí),狀態(tài)變?yōu)?ESTABLISHED
可靠傳輸
通過(guò)1、數(shù)據(jù)編號(hào)和積累確認(rèn) 2、以字節(jié)為單位的滑動(dòng)窗口 3、超時(shí)重傳時(shí)間 4、快速重傳 這四個(gè)方面來(lái)達(dá)到可靠傳輸?shù)哪康摹?/p>
1、數(shù)據(jù)編號(hào):將每個(gè)字節(jié)進(jìn)行編號(hào),有900個(gè)字節(jié),就從1到900進(jìn)行編號(hào)
1、積累確認(rèn):服務(wù)器端不是接收到一個(gè)字節(jié)就發(fā)一個(gè)確認(rèn),那樣效率太低,而是當(dāng)接收到4,5個(gè)時(shí),在發(fā)送一個(gè)確認(rèn),那么在之前的確認(rèn)之前的數(shù)據(jù)就算發(fā)送成功了的。
2、滑動(dòng)窗口:這個(gè)跟在數(shù)據(jù)鏈路層講個(gè)滑動(dòng)窗口一樣。每次能發(fā)送的數(shù)據(jù)是在此窗口中的,接到了多少數(shù)據(jù),就往后滑多少數(shù)據(jù)
3、超時(shí)重傳時(shí)間:這個(gè)也在鏈路層講過(guò),如果等待一段時(shí)間后,還沒(méi)接收到確認(rèn)報(bào)文,那么就重新傳
4、快速重傳:在滑動(dòng)窗口中的應(yīng)用,比如傳了1234 6到服務(wù)器端,老辦法是在4之后的所有數(shù)據(jù)度要重新傳,而這個(gè)快速重傳就只需要等待傳了5這個(gè)序號(hào),就可以繼續(xù)往下接收數(shù)據(jù)了。
流量控制
在傳輸層中,有接受緩存和發(fā)送緩存這兩個(gè)東西的存在,所以每次發(fā)送數(shù)據(jù)過(guò)去另一端時(shí),都會(huì)把這些數(shù)據(jù)給帶過(guò)去,讓對(duì)方知道自己的這兩個(gè)緩存的大小,然后來(lái)合理的設(shè)置自己的發(fā)送窗口的大小,如果對(duì)方的緩存快滿了,對(duì)方在傳送數(shù)據(jù)過(guò)來(lái)的時(shí)候,就會(huì)告訴自己,少發(fā)一點(diǎn)數(shù)據(jù)過(guò)來(lái),自己就設(shè)置滑動(dòng)窗口小一點(diǎn),讓對(duì)方有緩沖的機(jī)會(huì),而不會(huì)導(dǎo)致緩存溢出,不讓自己的報(bào)文被丟棄。
?
擁塞控制
其實(shí)跟流量控制差不多,但是站的角度更大,此時(shí)既考慮了對(duì)方接收不過(guò)來(lái),緩存太多溢出導(dǎo)致,又考慮在線路中,線路上的傳輸速率就那么大,但是有很多人同時(shí)用,發(fā)送的數(shù)據(jù)太多,就會(huì)使線路發(fā)現(xiàn)擁塞,也就是路由器可能轉(zhuǎn)發(fā)不過(guò)來(lái),導(dǎo)致大量數(shù)據(jù)丟失,這兩個(gè)問(wèn)題。所以擁塞控制這個(gè)解決方案,大概意思就是當(dāng)檢測(cè)到有網(wǎng)絡(luò)擁塞時(shí),就會(huì)讓自己的滑動(dòng)窗口變小,但具體是怎么變化的,就是根據(jù)算法來(lái)算了,
發(fā)送窗口的上限值 = Min[rwnd,cwnd] ? ?
rwnd:接受窗口,根據(jù)接受緩存,而定的接受窗口,接收緩存還有很多,那么接收窗口就大
cwnd:擁塞窗口,根據(jù)線路中的擁塞狀況來(lái)決定,線路中不擁塞,那么此窗口就大,
發(fā)送窗口是取兩個(gè)中較小值。這個(gè)還是可以理解的。
慢啟動(dòng)算法、快速恢復(fù)算法、結(jié)合來(lái)達(dá)到對(duì)擁塞進(jìn)行控制的,想了解這兩種算法的,百度一下百度百科
?
TCP釋放連接時(shí)的四次揮手
通信完成后,連接就會(huì)被釋放,通過(guò)四次揮手機(jī)制來(lái)完成這個(gè)事情。(畫(huà)來(lái)畫(huà)去還是覺(jué)得官方的圖好。)
?
第一次揮手:從ESTABLISHED變?yōu)橹鲃?dòng)關(guān)閉狀態(tài),客戶端主動(dòng)發(fā)送釋放連接請(qǐng)求給服務(wù)器端,FIN=1。發(fā)送完之后就變?yōu)镕IN_WAIT_1狀態(tài),這個(gè)狀態(tài)可以說(shuō)是等待確認(rèn)狀態(tài)。
第二次揮手:服務(wù)器接收到客戶端發(fā)來(lái)的釋放連接請(qǐng)求后,狀態(tài)變?yōu)镃LOSE_WAIT,然后發(fā)送確認(rèn)報(bào)文給客戶端,告訴他我接收到了你的請(qǐng)求。為什么變?yōu)镃LOSE_WAIT,原因是是客戶端發(fā)送的釋放連接請(qǐng)求,可能自己這端還有數(shù)據(jù)沒(méi)有發(fā)送完呢,所以這個(gè)時(shí)候整個(gè)TCP連接的狀態(tài)就變?yōu)榱税腙P(guān)閉狀態(tài)。服務(wù)器端還能發(fā)送數(shù)據(jù),并且客戶端也能接收數(shù)據(jù),但是客戶端不能在發(fā)送數(shù)據(jù)了,只能夠發(fā)送確認(rèn)報(bào)文??蛻舳私拥椒?wù)器的確認(rèn)報(bào)文后,就進(jìn)入了FIN_WAIT_2
狀態(tài)。也可以說(shuō)這是等待服務(wù)器釋放連接狀態(tài)。
第三次揮手:服務(wù)器端所有的數(shù)據(jù)度發(fā)送完了,認(rèn)為可以關(guān)閉連接了,狀態(tài)變?yōu)楸粍?dòng)關(guān)閉,所以向客戶端發(fā)送釋放連接報(bào)文,發(fā)完之后自己變?yōu)長(zhǎng)AST_WAIT狀態(tài),也就是等待客戶端確認(rèn)狀態(tài)
第四次揮手:客戶端接到釋放連接報(bào)文后,發(fā)送一個(gè)確認(rèn)報(bào)文,然后自己變?yōu)門(mén)IME_WAIT,而不是立馬關(guān)閉,因?yàn)榭蛻舳税l(fā)送的確認(rèn)報(bào)文可能會(huì)丟失,丟失的話服務(wù)器就會(huì)重傳一個(gè)FIN,也就是釋放連接報(bào)文,這個(gè)時(shí)候客戶端必須還沒(méi)關(guān)閉。 當(dāng)服務(wù)器接受到確認(rèn)報(bào)文后,服務(wù)器就進(jìn)入CLOSE狀態(tài),也就是關(guān)閉了。但是由于上面說(shuō)的這個(gè)原因,客戶端必須等待一定的時(shí)間才能夠進(jìn)入CLOSE狀態(tài)。
上面就是TCP連接釋放的四次揮手機(jī)制。很簡(jiǎn)單把。
?
同時(shí)關(guān)閉連接
正常情況下,通信一方請(qǐng)求連接關(guān)閉,另一方響應(yīng)連接關(guān)閉請(qǐng)求,并且被動(dòng)關(guān)閉連接。但是若出現(xiàn)同時(shí)關(guān)閉連接請(qǐng)求時(shí),通信雙方均從 ESTABLISHED 狀態(tài)轉(zhuǎn)換為 FIN_WAIT_1 狀態(tài)。任意一方收到對(duì)方發(fā)來(lái)的 FIN 報(bào)文段后,其狀態(tài)均由 FIN_WAIT_1轉(zhuǎn)變到 CLOSING 狀態(tài),并發(fā)送最后的 ACK 數(shù)據(jù)段。當(dāng)收到最后的 ACK 數(shù)據(jù)段后,狀態(tài)轉(zhuǎn)變化 TIME_WAIT,在等待 2MSL 時(shí)間后進(jìn)入到 CLOSED 狀態(tài),最終釋放整個(gè) TCP 傳輸連接。其過(guò)程入下
?
?
舉一個(gè)使用tcp的例子,一般需要保證數(shù)據(jù)可靠時(shí),度會(huì)使用tcp協(xié)議。
1、http協(xié)議進(jìn)行網(wǎng)站的訪問(wèn)時(shí),使用的就是tcp。
?
總結(jié)
以上是生活随笔為你收集整理的第五章 运输层(UDP和TCP三次握手,四次挥手分析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: node.js之stream模块
- 下一篇: [转载]Google Guava官方教程