銀川網(wǎng)站建設(shè)廣告公司百度seo優(yōu)化方法
文章目錄
- TCP UDP協(xié)議
- 1. 概述
- 2. 端口號(hào) 復(fù)用 分用
- 3. TCP
- 3.1 TCP首部格式
- 3.2 建立連接-三次握手
- 3.3 釋放連接-四次揮手
- 3.4 TCP流量控制
- 3.5 TCP擁塞控制
- 3.6 TCP可靠傳輸?shù)膶?shí)現(xiàn)
- 3.7 TCP超時(shí)重傳
- 4. UDP
- 5.TCP與UDP的區(qū)別
TCP UDP協(xié)議
1. 概述
TCP、UDP協(xié)議是TCP/IP體系結(jié)構(gòu)傳輸層中的兩個(gè)重要協(xié)議。
如圖所示為計(jì)算機(jī)網(wǎng)絡(luò)四層模型:
**IP協(xié)議
**是網(wǎng)際層中的核心協(xié)議,它可以互聯(lián)不同的網(wǎng)絡(luò)接口,并向其上層提供無(wú)連接、不可靠的數(shù)據(jù)傳輸服務(wù)
。
TCP/IP體系結(jié)構(gòu)的應(yīng)用層中包含許大量的應(yīng)用層協(xié)議,其中有些應(yīng)用層協(xié)議需要使用可靠傳輸服務(wù),例如瀏覽網(wǎng)頁(yè)、傳輸文件等,這些數(shù)據(jù)一旦傳輸失敗會(huì)造成無(wú)法挽回的危害。而有些則需要使用不可靠傳輸服務(wù),例如音視頻通話等,少量的數(shù)據(jù)傳輸錯(cuò)誤并不會(huì)對(duì)播放造成大影響。
由于應(yīng)用層需要使用可靠和不可靠?jī)煞N傳輸服務(wù),但I(xiàn)P協(xié)議只能提供不可靠傳輸服務(wù),于是就需要傳輸層來(lái)提供可靠/不可靠的傳輸服務(wù)
。
其中TCP提供可靠性傳輸服務(wù),UDP提供不可靠傳輸服務(wù)
。
TCP
:T
ransmission C
ontrol P
rotocol,傳輸控制協(xié)議
,為上層提供的是面向連接的可靠的數(shù)據(jù)傳輸服務(wù)
。使用TCP通信的雙方,在傳送數(shù)據(jù)之前必須首先建立TCP連接
(邏輯連接,而非物理連接)。數(shù)據(jù)傳輸結(jié)束后必須要釋放TCP連接
。TCP為了實(shí)現(xiàn)可靠傳輸,就必須使用很多措施,例如TCP連接管理、確認(rèn)機(jī)制、超時(shí)重傳、流量控制、擁塞控制
等。TCP的實(shí)現(xiàn)復(fù)雜,報(bào)文首部較大,占用處理機(jī)資源比較多。
UDP
:U
ser D
atagram P
rotocol,用戶數(shù)據(jù)報(bào)協(xié)議
,為其上層提供的是無(wú)連接的不可靠的數(shù)據(jù)傳輸服務(wù)
,因此不需要實(shí)現(xiàn)可靠傳輸?shù)母鞣N機(jī)制。使用UDP通信的雙方,在傳送數(shù)據(jù)之前不需要建立連接。UDP的實(shí)現(xiàn)簡(jiǎn)單,用戶數(shù)據(jù)報(bào)首部比較小。
2. 端口號(hào) 復(fù)用 分用
端口號(hào)
:運(yùn)行在計(jì)算機(jī)上的進(jìn)程使用進(jìn)程標(biāo)識(shí)符PID
來(lái)區(qū)分,但是因特網(wǎng)上的計(jì)算機(jī)使用操作系統(tǒng)復(fù)雜,不同的操作系統(tǒng)又有不同格式的進(jìn)程標(biāo)識(shí)符,為了使運(yùn)行在不同操作系統(tǒng)的計(jì)算機(jī)的應(yīng)用進(jìn)程之間能夠進(jìn)行通信,就必須使用統(tǒng)一的方法對(duì)TCP/IP體系的應(yīng)用進(jìn)程進(jìn)行標(biāo)識(shí)
,而這個(gè)標(biāo)識(shí)方法就是**端口號(hào)
**,運(yùn)輸層使用端口號(hào)來(lái)區(qū)分應(yīng)用層的不同應(yīng)用進(jìn)程。端口號(hào)只具有本地意義,即端口號(hào)只是為了標(biāo)識(shí)本計(jì)算機(jī)應(yīng)用進(jìn)程,在因特網(wǎng)中,不同的計(jì)算機(jī)中的相同端口沒(méi)有聯(lián)系,你電腦上的8080端口跟我電腦上的8080端口一點(diǎn)關(guān)系沒(méi)有。
發(fā)送方的復(fù)用 :應(yīng)用層報(bào)文經(jīng)過(guò)傳輸層TCP協(xié)議進(jìn)行封裝,稱為T(mén)CP復(fù)用。應(yīng)用層報(bào)文經(jīng)過(guò)傳輸層UDP協(xié)議封裝,稱為UDP復(fù)用。傳輸層的報(bào)文經(jīng)過(guò)網(wǎng)絡(luò)層IP協(xié)議的封裝,稱為IP復(fù)用
接收方的分用:網(wǎng)絡(luò)層使用IP協(xié)議解析接受的IP數(shù)據(jù)報(bào),稱為IP分用。傳輸層使用TCP協(xié)議解析接受的TCP數(shù)據(jù)報(bào),稱為T(mén)CP分用。傳輸層使用UDP協(xié)議解析接受的UDP數(shù)據(jù)報(bào),稱為UDP分用。
?
3. TCP
3.1 TCP首部格式
TCP協(xié)議處于傳輸層,它向上層(應(yīng)用層)提供面向連接的可靠傳輸服務(wù)
,為了實(shí)現(xiàn)可靠傳輸,采用了**面向字節(jié)流
**的方式。
TCP在發(fā)送數(shù)據(jù)時(shí)從發(fā)送緩存中取出一部分或全部字節(jié)并給其添加一個(gè)首部使之成為T(mén)CP報(bào)文段后在發(fā)送給下層。一個(gè)TCP報(bào)文段由首部
和數(shù)據(jù)載荷
兩部分組成,TCP實(shí)現(xiàn)連接管理、確認(rèn)機(jī)制、超時(shí)重傳、流量控制、擁塞控制這些功能都體現(xiàn)在它首部中各字段的作用。
TCP首部由兩部分構(gòu)成 :20字節(jié)的固定首部和最大40字節(jié)的擴(kuò)展首部。也就是說(shuō),一個(gè)TCP首部的字節(jié)數(shù)在20~60字節(jié)之間。
源端口 :16比特,即兩字節(jié),寫(xiě)入源端口號(hào),用于標(biāo)識(shí)發(fā)送
該TCP報(bào)文段的應(yīng)用進(jìn)程。
目的端口 :16比特,即兩字節(jié),寫(xiě)入目的端口號(hào),用于標(biāo)識(shí)接受
該TCP報(bào)文段的應(yīng)用進(jìn)程。
假如我們使用web服務(wù)127.0.0.1:8080遠(yuǎn)程訪問(wèn)MySQL服務(wù)器48.104.60.218:3306;源端口就是我們自己的IP地址中的端口8080,目的端口就是MySQL服務(wù)器的IP地址中的端口3306。
接下來(lái)看看與TCP實(shí)現(xiàn)可靠性傳輸有關(guān)的三個(gè)字段 :序號(hào)、確認(rèn)號(hào)、ACK。
序號(hào) :占32比特,取值范圍[0, 2^32 - 1],序號(hào)增加到最后一個(gè)后,下一個(gè)序號(hào)就又回到0。序號(hào)的值用來(lái)指出本TCP報(bào)文段**數(shù)據(jù)載荷**第一個(gè)字節(jié)的序號(hào)
。如圖所示,首部的序號(hào)即為數(shù)據(jù)載荷第一個(gè)字節(jié)的序號(hào)122。
確認(rèn)號(hào) :占32比特,取值范圍[0, 2^32 - 1],確認(rèn)好增加到最后一個(gè)后,下一個(gè)確認(rèn)好又回到0。確認(rèn)號(hào)的值用于指出期望收到對(duì)方下一個(gè)TCP報(bào)文段的數(shù)據(jù)載荷的第一個(gè)字節(jié)的序號(hào),同時(shí)也是對(duì)之前收到的所有數(shù)據(jù)的確認(rèn)
??梢赃@樣理解:若確認(rèn)號(hào)為n,則代表之前已經(jīng)成功接收到序號(hào)為n-1的報(bào)文段,下一次期望收到序號(hào)為n的報(bào)文段。只有ACK標(biāo)識(shí)的值為1時(shí),確認(rèn)號(hào)字段才有效。
ACK :確標(biāo)志位,取值為1時(shí)確認(rèn)號(hào)才有效;取值為0時(shí)確認(rèn)號(hào)無(wú)效。TCP規(guī)定,連接建立后所有的TCP報(bào)文段都必須把ACK置為1。
如圖,客戶端向服務(wù)端發(fā)送一個(gè)TCP數(shù)據(jù)報(bào),序號(hào)為200代表此數(shù)據(jù)報(bào)的數(shù)據(jù)載荷部分的第一個(gè)字節(jié)的序號(hào)為200。確認(rèn)號(hào)為800代表客戶端已經(jīng)收到服務(wù)端發(fā)送的序號(hào)為799號(hào)以及之前的數(shù)據(jù)報(bào),現(xiàn)在想要序號(hào)為800的數(shù)據(jù)報(bào)
。ACK的值為1保證確認(rèn)號(hào)有效。數(shù)據(jù)載荷長(zhǎng)度代表此次傳輸?shù)淖止?jié)數(shù)。也就是說(shuō),此次傳輸?shù)臄?shù)據(jù)載荷部分的序號(hào)為 200 - 300。
數(shù)據(jù)偏移 :占4比特,并以4字節(jié)為單位。用于指出TCP報(bào)文段的數(shù)據(jù)載荷部分的起始處距離TCP報(bào)文段的起始處有多遠(yuǎn)。這個(gè)字段實(shí)際上是指出了TCP報(bào)文段的首部有多少個(gè)字節(jié)
。同時(shí),它的值是首部字節(jié)數(shù)除以4的。首部的字節(jié)數(shù)范圍為:20 ~ 60,所以數(shù)據(jù)偏移字段的值范圍為 5~15,即 0101到1111。
保留 :占6比特,保留以后使用。目前值為0。
窗口 :占16比特,以字節(jié)為單位。指出發(fā)送本報(bào)文段的一方的接收窗口
。窗口值作為接收方讓發(fā)送方設(shè)置其發(fā)送窗口的依據(jù)。這是以接收方的接受能力來(lái)控制發(fā)送方的發(fā)送能力,稱為流量控制。需要注意的是,發(fā)送窗口的大小還取決于擁塞窗口的大小,也就是從接收窗口和擁塞窗口中取最小值。
校驗(yàn)和 :占16比特,用于檢查整個(gè)TCP報(bào)文段在傳輸過(guò)程中是否出現(xiàn)了誤碼。
緊急指針 :占16比特,以字節(jié)為單位,用來(lái)指明緊急數(shù)據(jù)的長(zhǎng)度。當(dāng)發(fā)送方有緊急數(shù)據(jù)時(shí),可將緊急數(shù)據(jù)插隊(duì)到發(fā)送緩存的最前面,并立刻封裝到一個(gè)TCP報(bào)文中進(jìn)行發(fā)送。緊急指針會(huì)指出本報(bào)文段數(shù)據(jù)載荷部分包含了多長(zhǎng)的緊急數(shù)據(jù),緊急數(shù)據(jù)之后是普通數(shù)據(jù)。
SYN :同步標(biāo)志位,在TCP連接建立時(shí)用來(lái)同步序號(hào)
。TCP規(guī)定,SYN值為1時(shí)代表正在建立連接,此報(bào)文段不能攜帶數(shù)據(jù)
。
FIN :終止標(biāo)志位,用于釋放TCP連接
。TCP規(guī)定,FIN值為1時(shí)代表正在釋放連接,此報(bào)文段不能攜帶數(shù)據(jù)
。
RST ?:復(fù)位標(biāo)志位,用于復(fù)位TCP連接。當(dāng)RST為1時(shí),表示TCP連接出現(xiàn)了異常,此時(shí)必須先斷開(kāi)連接,再重新建立連接。RST還用來(lái)拒絕非法報(bào)文段或拒絕TCP連接。
PSH ?:推送標(biāo)志位,用來(lái)實(shí)現(xiàn)推送操作。當(dāng)接受方收到該標(biāo)志位為1的報(bào)文段會(huì)盡快上交應(yīng)用進(jìn)程,而不必等到接收緩存都填滿后再向上交付。
URG :緊急標(biāo)志位,與緊急指針字段共同實(shí)現(xiàn)緊急操作。緊急標(biāo)志位URG為1時(shí),緊急指針有效,為0時(shí)緊急指針無(wú)效。
選項(xiàng) :選項(xiàng)中的字段都是可選值,擴(kuò)展功能。選項(xiàng)的字節(jié)數(shù)可變
填充 ?:由于選項(xiàng)的字節(jié)數(shù)可變,那就使用填充字段確保報(bào)文段首部能被4整除。假如選項(xiàng)有3字節(jié),那么填充就只有1個(gè)字節(jié)。
為什么一定要確保首部字節(jié)數(shù)要能被4整除?因?yàn)閿?shù)據(jù)偏移字段的值是首部字節(jié)數(shù)除以4。
3.2 建立連接-三次握手
TCP是面向連接的協(xié)議,它基于運(yùn)輸連接來(lái)傳送TCP報(bào)文段。TCP運(yùn)輸連接的建立和釋放是每一次面向娘連接的通信中必不可少的過(guò)程
。
TCP運(yùn)輸連接分為以下三個(gè)階段:
- 通過(guò)三次握手建立TCP連接
- 進(jìn)行數(shù)據(jù)傳輸
- 通過(guò)四次揮手?jǐn)嚅_(kāi)TCP連接
先來(lái)介紹一下TCP連接的建立 :三報(bào)文握手
最初,TCP客戶端與TCP服務(wù)端的TCP進(jìn)程都處于關(guān)閉狀態(tài)
,即CLOSED
。
一開(kāi)始,TCP服務(wù)端先創(chuàng)建TCP傳輸控制塊,用于存儲(chǔ)TCP連接中的以下重要信息,例如TCP連接表、指向發(fā)送和接受緩存的指針、指向重傳隊(duì)列的指針…TCP服務(wù)端創(chuàng)建傳輸控制塊后就進(jìn)入監(jiān)聽(tīng)狀態(tài)(LISTEN)
等待接受TCP客戶端的連接請(qǐng)求。
TCP客戶端在發(fā)起連接請(qǐng)求之前也要?jiǎng)?chuàng)建傳輸控制塊,之后發(fā)起連接請(qǐng)求。
第一次握手
:
TCP客戶端進(jìn)程向TCP服務(wù)端進(jìn)程發(fā)送TCP連接請(qǐng)求報(bào)文段
,并進(jìn)入同步已發(fā)送狀態(tài)(SYN-SEND)
。
此連接請(qǐng)求報(bào)文段首部中的值:
-
SYN :1,表明這是一個(gè)TCP連接請(qǐng)求報(bào)文段。同時(shí)規(guī)定此時(shí)的報(bào)文段不能攜帶數(shù)據(jù)。
-
序號(hào)(seq) :初始值x
第二次握手
:
TCP服務(wù)端接收到請(qǐng)求連接報(bào)文后,如果同意連接,會(huì)向TCP客戶端發(fā)送 連接請(qǐng)求確認(rèn)報(bào)文段
,并進(jìn)入同步已接受狀態(tài)(SYN-RCVD)
。
該報(bào)文段首部中的值:
-
SYN :1,表明現(xiàn)在正在進(jìn)行TCP連接。同時(shí)規(guī)定此時(shí)的報(bào)文段不能攜帶數(shù)據(jù)。
-
ACK :使確認(rèn)號(hào)生效。
-
確認(rèn)號(hào)(ack) :由于客戶端發(fā)送的序號(hào)為x,那么確認(rèn)號(hào)就是x+1,代表“我已經(jīng)收到序號(hào)為x以及之前的數(shù)據(jù)了,你下次給我發(fā)x+1吧”。
-
序號(hào)(seq) :初始值y。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-4nZdkdLy-1678504984186)(assets/image-20230308181233-f7ep57n.png)]?
第三次握手
:
TCP客戶端收到連接請(qǐng)求確認(rèn)報(bào)文段后,還需要向TCP服務(wù)端進(jìn)程發(fā)送一個(gè)**普通
的TCP確認(rèn)報(bào)文段
,并進(jìn)入連接已建立狀態(tài)(ESTABLISHED)
。由于是一個(gè)普通**的連接建立報(bào)文段,所以它的SYN字段值并不為1,所以這個(gè)報(bào)文段可以攜帶數(shù)據(jù),但是它不攜帶數(shù)據(jù)。
(TCP規(guī)定,SYN為1的報(bào)文段不能攜帶數(shù)據(jù),報(bào)文段發(fā)送時(shí)消耗一個(gè)序號(hào)。SYN不為1的報(bào)文段可以攜帶數(shù)據(jù),如果不攜帶數(shù)據(jù),不消耗序號(hào))
該報(bào)文段的首部值:
- ACK :1,保證確認(rèn)位可用。
- 序號(hào)(seq) :x+1,因?yàn)門(mén)CP服務(wù)端上次發(fā)的報(bào)文中的確認(rèn)號(hào)為x+1。由于SYN值不為1,并且沒(méi)有攜帶數(shù)據(jù),故x+1這個(gè)序號(hào)下次還能用,也就是建立連接后還可以再使用一次x+1這個(gè)序號(hào)。
- 確認(rèn)號(hào)(ack) :y+1,因?yàn)門(mén)CP服務(wù)端上次發(fā)送的報(bào)文段的序號(hào)為y,所以我們這次發(fā)送y+1,表示我們已經(jīng)接收到了序號(hào)y以及之前的數(shù)據(jù),下次我們想要序號(hào)為y+1的數(shù)據(jù)。
當(dāng)TCP服務(wù)端接收到TCP客戶端第二次報(bào)文時(shí),服務(wù)端也進(jìn)入連接已建立狀態(tài)(ESTABLISHED)
。
現(xiàn)在,雙方都已進(jìn)入連接建立狀態(tài),可以根據(jù)已經(jīng)建立好的TCP連接進(jìn)行可靠的數(shù)據(jù)傳輸。
那么為什么建立TCP連接一定需要三次呢?為什么不能是兩次?為什么不能使用兩次報(bào)文握手建立連接呢?
接下來(lái)看看兩報(bào)文握手會(huì)出現(xiàn)的問(wèn)題 :
TCP客戶端發(fā)出請(qǐng)求連接報(bào)文,但是因?yàn)榫W(wǎng)絡(luò)問(wèn)題長(zhǎng)時(shí)間停滯在網(wǎng)絡(luò)中,于是觸發(fā)超時(shí)重傳機(jī)制,TCP客戶端重新發(fā)起TCP連接請(qǐng)求報(bào)文段,這次成功建立連接。之后便是數(shù)據(jù)的傳輸,最后數(shù)據(jù)傳輸完成,服務(wù)端與客戶端斷開(kāi)連接。
斷開(kāi)連接后突然,上次因?yàn)榫W(wǎng)絡(luò)問(wèn)題滯后的TCP連接請(qǐng)求發(fā)送到了TCP服務(wù)端,服務(wù)端以為客戶端想要再次建立TCP連接,于是服務(wù)端進(jìn)入監(jiān)聽(tīng)(LISTEN)狀態(tài)并向客戶端發(fā)送連接請(qǐng)求確認(rèn)報(bào)文,但是客戶端此時(shí)為關(guān)閉狀態(tài),對(duì)連接請(qǐng)求確認(rèn)報(bào)文不予理睬,于是服務(wù)端一直處于監(jiān)聽(tīng)狀態(tài)并發(fā)送連接請(qǐng)求確認(rèn)報(bào)文。這就造成了TCP服務(wù)端資源的浪費(fèi)。
綜上所述,采用三報(bào)文握手而不是兩報(bào)文握手是為了防止已失效的連接請(qǐng)求報(bào)文段突然傳送到了TCP服務(wù)端因而導(dǎo)致的錯(cuò)誤
。
3.3 釋放連接-四次揮手
TCP通過(guò)四次揮手來(lái)結(jié)束TCP的連接。
在斷開(kāi)連接之前,客戶端與服務(wù)端都處于連接已建立狀態(tài)(ESTABLISHED)
。
第一次揮手 :
TCP客戶端會(huì)發(fā)送TCP連接釋放報(bào)文段
,進(jìn)入終止等待1狀態(tài)(FIN-WAIT-1)
。TCP連接釋放報(bào)文段的字段值為:
- FIN :1,代表此時(shí)正在釋放TCP連接,此報(bào)文段不能攜帶數(shù)據(jù)。
- ACK :使確認(rèn)號(hào)生效。
- seq(序號(hào)) :u,代表此報(bào)文段的數(shù)據(jù)載荷的第一個(gè)字節(jié)的序號(hào)為u。
- ack(確認(rèn)號(hào)) :v,代表已經(jīng)收到序號(hào)為v-1的數(shù)據(jù),下次想要序號(hào)為v的數(shù)據(jù)。
?
第二次揮手
:
服務(wù)端接收到客戶端發(fā)送的TCP連接釋放報(bào)文段后,會(huì)向客戶端發(fā)送一個(gè)普通的TCP確認(rèn)報(bào)文段
,并進(jìn)入關(guān)閉等待狀態(tài)(CLOSE-WAIT)
。
(此時(shí)的TCP連接進(jìn)入了半關(guān)閉狀態(tài),因?yàn)榭蛻舳说椒?wù)端的TCP連接進(jìn)入關(guān)閉狀態(tài),因?yàn)榭蛻舳艘呀?jīng)沒(méi)有數(shù)據(jù)要發(fā)送了;但是服務(wù)端到客戶端的TCP連接通道還沒(méi)關(guān)閉,因?yàn)榉?wù)端要繼續(xù)發(fā)送那些還未發(fā)送完畢的數(shù)據(jù)。)
此報(bào)文段的字段值 :
- ACK :1,保證確認(rèn)號(hào)有效
- 序號(hào)(seq) :v,代表此報(bào)文段的數(shù)據(jù)載荷的第一個(gè)字節(jié)的序號(hào)為v。
- 確認(rèn)號(hào)(ack) :u+1,代表已經(jīng)收到客戶端發(fā)送的第u條數(shù)據(jù),下次想要u+1。
TCP客戶端收到TCP服務(wù)端發(fā)送的TCP確認(rèn)報(bào)文段后就會(huì)進(jìn)入終止等待2狀態(tài)(FIN-WAIT2)
。
??
第三次揮手
:
當(dāng)TCP服務(wù)端所有剩余數(shù)據(jù)發(fā)送完畢后,TCP服務(wù)端會(huì)發(fā)送TCP連接釋放報(bào)文段
,并進(jìn)入最后確認(rèn)狀態(tài)(LAST-ACK)
。
該報(bào)文段的字段:
- FIN :1,表示正在釋放連接。
- ACK :1,保證確認(rèn)號(hào)有效。
- 序號(hào)(seq) :w,為什么不是v+1?因?yàn)榈诙螕]手之后可能傳輸了其他剩余數(shù)據(jù)報(bào)。
- 確認(rèn)號(hào)(ack) :u+1。為什么是u+1?不是又發(fā)送了剩余數(shù)據(jù)嗎?因?yàn)槭S鄶?shù)據(jù)報(bào)只是服務(wù)端向客戶端發(fā)送,客戶端向服務(wù)端的TCP連接通道已經(jīng)斷開(kāi)。
?
第四次揮手
:
收到服務(wù)端發(fā)送的TCP連接釋放報(bào)文段后,客戶端發(fā)送普通的確認(rèn)報(bào)文段
,之后進(jìn)入時(shí)間等待狀態(tài)(TIME-WAIT)
。
收到該報(bào)文段后,服務(wù)端關(guān)閉。處于時(shí)間等待狀態(tài)2MSL(2mins)后,客戶端TCP連接關(guān)閉。
該報(bào)文字段值 :
- ACK :1,保證確認(rèn)號(hào)有效
- 序號(hào)(seq) :u+1
- 確認(rèn)號(hào)(ack) :w+1
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-u0RBO0Rt-1678504984188)(assets/image-20230309151435-5c57p7p.png)]?
為什么客戶端還要等待兩分鐘再關(guān)閉TCP連接呢?
假如不進(jìn)行等待而直接關(guān)閉,也就是客戶端發(fā)送第四次揮手之后立即關(guān)閉TCP連接。那么如果最后一個(gè)確認(rèn)報(bào)文丟失,此時(shí)客戶端已經(jīng)關(guān)閉,但服務(wù)端還在等待最后的確認(rèn)保報(bào)文,一直沒(méi)等到就會(huì)觸發(fā)超時(shí)重傳機(jī)制發(fā)送第三次揮手報(bào)文,但是客戶端已經(jīng)關(guān)閉,那么服務(wù)端就會(huì)一直發(fā)送第三次揮手報(bào)文,非常浪費(fèi)資源。而等待兩分鐘就可以解決這個(gè)問(wèn)題,客戶端有足夠時(shí)間等待服務(wù)端發(fā)送的超時(shí)重傳報(bào)文。
?
至此,四報(bào)文揮手過(guò)程完畢。
接下來(lái)看看?;钣?jì)時(shí)器 :
在客戶端與服務(wù)端建立連接后,如果客戶端出現(xiàn)故障,應(yīng)當(dāng)有措施讓服務(wù)端主動(dòng)斷開(kāi)連接而不是一直等待下去。這時(shí)就要使用到?;钣?jì)時(shí)器。
- TCP服務(wù)器進(jìn)程每收到一次TCP客戶進(jìn)程的數(shù)據(jù),就重新設(shè)置并啟動(dòng)?;钣?jì)時(shí)器(定時(shí)2小時(shí))。
- 若2小時(shí)內(nèi)沒(méi)接收到TCP客戶端發(fā)送的數(shù)據(jù),則
當(dāng)保活計(jì)時(shí)器到時(shí)后,TCP服務(wù)器向TCP客戶端發(fā)送一個(gè)探測(cè)報(bào)文段,以后則每75秒發(fā)送一次,若連續(xù)10個(gè)報(bào)文段都無(wú)響應(yīng),TCP服務(wù)端主動(dòng)斷開(kāi)TCP連接
。
3.4 TCP流量控制
為什么需要流量控制?一般來(lái)說(shuō),我們更加希望傳輸速度越快越好,但是如果發(fā)送方發(fā)送數(shù)據(jù)的速度過(guò)快,會(huì)導(dǎo)致接受方來(lái)不及接收,這就會(huì)造成數(shù)據(jù)的丟失。
所以流量控制就是為了讓發(fā)送方發(fā)送的速率不要太快,要讓接受方來(lái)得及接收
。
TCP的流量控制是通過(guò)滑動(dòng)窗口來(lái)實(shí)現(xiàn)的。如果此時(shí)A向B傳輸數(shù)據(jù),在傳輸數(shù)據(jù)前B告訴A:我的接收窗口rwnd=400(receiver window)。這表示 :發(fā)送方A的發(fā)送窗口不能超過(guò)接受方B的接收窗口的值,也就是400字節(jié)。
假如B最初的接收窗口大小為400,那么A可以發(fā)送400字節(jié)的數(shù)據(jù)。B接收400字節(jié)數(shù)據(jù)并發(fā)送確認(rèn)后,這400字節(jié)的數(shù)據(jù)會(huì)先從A的發(fā)送緩存中刪除?,F(xiàn)在A成功向B發(fā)送了400字節(jié)的數(shù)據(jù),但是B的接收緩存沒(méi)多少空間了,于是B對(duì)A說(shuō):我的接收窗口為rwnd=300。這表示發(fā)送方A的發(fā)送窗口不能超過(guò)300字節(jié)。就這樣,如果發(fā)送后B的發(fā)送緩存還沒(méi)騰出空間,會(huì)繼續(xù)減小接收窗口直到B的發(fā)送緩存沒(méi)有空間,這時(shí)B向A發(fā)送的rwnd=0,即零窗口通知
,代表不要再發(fā)送數(shù)據(jù)了,等我騰出空間再說(shuō)吧。
如果A發(fā)送的數(shù)據(jù)丟失怎么辦呢?
A給B發(fā)送消息,如果數(shù)據(jù)丟失,并不會(huì)影響A后續(xù)數(shù)據(jù)的發(fā)送,B發(fā)送的ack消息會(huì)告訴A哪些數(shù)據(jù)還沒(méi)有發(fā)送,到時(shí)A重新發(fā)送即可。
如果B發(fā)送的rwnd丟失怎么辦呢?
如果B發(fā)送給A的rwnd丟失,A一直在等待B發(fā)送的窗口通知(rwnd)以便設(shè)置自己的發(fā)送窗口,而主機(jī)B以為A已經(jīng)接收到窗口通知,他就一直等待A發(fā)送的數(shù)據(jù),這就會(huì)造成死鎖的局面。為了解決這個(gè)問(wèn)題,TCP為每一個(gè)連接設(shè)置一個(gè)持續(xù)定時(shí)器
。
如果B給A發(fā)送零窗口通知,持續(xù)計(jì)時(shí)器會(huì)重新計(jì)時(shí),當(dāng)持續(xù)計(jì)時(shí)器超時(shí)時(shí),證明已經(jīng)很久沒(méi)有收到零窗口通知了,A就給B發(fā)送一個(gè)探測(cè)報(bào)文,B接收該報(bào)文后,將自己的接收窗口值發(fā)送給A,如果此值為0,則持續(xù)計(jì)時(shí)器重新計(jì)時(shí);如果此值為其他值,A將其發(fā)送窗口大小設(shè)置為此值。于是死鎖問(wèn)題得以解決。
3.5 TCP擁塞控制
擁塞 :對(duì)網(wǎng)絡(luò)中某一資源的需求超過(guò)了該資源所能提供的可用部分,網(wǎng)絡(luò)性能就要變壞。這種情況叫做擁塞(congestion)
。
若出現(xiàn)擁塞而不進(jìn)行控制,整個(gè)網(wǎng)絡(luò)的吞吐量將隨輸入負(fù)荷的增大而下降。
TCP對(duì)擁塞控制提供了四種算法 :
- 慢開(kāi)始(slow-start)
- 擁塞避免(congestion avoidance)
- 快重傳(fast retransmit)
- 快恢復(fù)(fast recovery)
為了簡(jiǎn)單起見(jiàn),我們假設(shè)發(fā)送方A,接收方B,A只發(fā)送數(shù)據(jù)報(bào),B只發(fā)送確認(rèn)報(bào)。并且接收方的接收窗口足夠大,此時(shí)發(fā)送方的發(fā)送窗口就只受擁塞控制的影響。
發(fā)送方維護(hù)一個(gè)叫做擁塞窗口cwnd
的狀態(tài)變量,其值取決于網(wǎng)絡(luò)的擁塞程度,并且動(dòng)態(tài)變化
。
- 擁塞窗口cwnd的維護(hù)原則:只要網(wǎng)絡(luò)沒(méi)有出現(xiàn)擁塞,擁塞窗口就再增大一些。網(wǎng)絡(luò)出現(xiàn)擁塞,擁塞窗口就減小一些。
- 判斷出現(xiàn)網(wǎng)絡(luò)擁塞的依據(jù):沒(méi)有按時(shí)收到應(yīng)當(dāng)?shù)竭_(dá)的確認(rèn)報(bào)文段(即發(fā)生超時(shí))
發(fā)送方將擁塞窗口作為發(fā)送窗口swnd,即swnd = cwnd。
具體的擁塞控制可以參考 :https://juejin.cn/post/6844903664566403085
實(shí)在是講不出來(lái)😢
3.6 TCP可靠傳輸?shù)膶?shí)現(xiàn)
TCP基于以字節(jié)為單位的滑動(dòng)窗口來(lái)實(shí)現(xiàn)可靠傳輸。
如圖A與B建立了TCP連接
(簡(jiǎn)單起見(jiàn),我們假設(shè)數(shù)據(jù)單方面發(fā)送并且沒(méi)有擁塞影響,即A發(fā)送數(shù)據(jù)報(bào)文段,B只發(fā)送確認(rèn)報(bào)文段,并且發(fā)送窗口不會(huì)受到擁塞控制的影響)
上方表格為待傳輸?shù)臄?shù)據(jù)的序號(hào)。
?
連接建立后B給A發(fā)送一個(gè)確認(rèn)報(bào)文段:rwnd=20, ack=23,代表滑動(dòng)窗口大小為20,下一次給我傳序號(hào)為23的數(shù)據(jù)。
發(fā)送方接收到這個(gè)確認(rèn)報(bào)文段后構(gòu)造出自己的發(fā)送窗口,大小為20字節(jié),發(fā)送窗口從序號(hào)為23的數(shù)據(jù)開(kāi)始,它稱為后沿;直到序號(hào)為42的數(shù)據(jù)結(jié)束,它稱為前沿。
并且,由于ack=23,發(fā)送方A可以將23號(hào)以前的數(shù)據(jù)從發(fā)送緩存中刪除,在接收到ack之前,發(fā)送窗口中的數(shù)據(jù)都要留在發(fā)送緩存中。
發(fā)送窗口中的數(shù)據(jù)都是可以發(fā)送的數(shù)據(jù),發(fā)送窗口前沿右邊的數(shù)據(jù)都是不允許發(fā)送的數(shù)據(jù)。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-S5SWkMJ5-1678504984188)(assets/image-20230310181508-0jd6o6q.png)]???
后沿的移動(dòng)情況有兩種 :不動(dòng)、前移
前沿的移動(dòng)情況有三種 :不動(dòng)、前移、后移。
接下來(lái)A向B發(fā)送10個(gè)字節(jié)的數(shù)據(jù),序號(hào)為23-33的數(shù)據(jù)被發(fā)送出去,但是并不會(huì)從發(fā)送緩存中刪除,因?yàn)檫€沒(méi)有收到確認(rèn)ack。
??
假如接收方B收到了序號(hào)為25-27的數(shù)據(jù),由于23-24的數(shù)據(jù)還沒(méi)接收到,所以B發(fā)送的確認(rèn)報(bào)文的確認(rèn)號(hào)仍為23。這是接收方對(duì)23號(hào)數(shù)據(jù)發(fā)起的第一次重復(fù)確認(rèn),因此不會(huì)觸發(fā)超時(shí)重傳機(jī)制。同時(shí)接收窗口為20沒(méi)變。
??
當(dāng)以后23-24號(hào)數(shù)據(jù)傳到接收方,接收方就會(huì)發(fā)送對(duì)于23-27號(hào)數(shù)據(jù)的確認(rèn)報(bào)文,如果rwnd的值仍為20,接收方就會(huì)將接收窗口移動(dòng)到28-47號(hào)數(shù)據(jù)。
發(fā)送方收到該確認(rèn)報(bào)文后將23-27號(hào)數(shù)據(jù)從發(fā)送緩存中刪除。同時(shí)發(fā)送窗口移動(dòng)到28-47號(hào)數(shù)據(jù)。
?
當(dāng)發(fā)送方發(fā)送的數(shù)據(jù)遲遲無(wú)法到達(dá)接收方,重傳計(jì)時(shí)器超時(shí),會(huì)重傳發(fā)送窗口內(nèi)已發(fā)送的數(shù)據(jù),并重新啟動(dòng)重傳計(jì)時(shí)器
。
注意 :
-
雖然發(fā)送方的發(fā)送窗口是根據(jù)接收方的接收窗口設(shè)置的,但是在同一時(shí)刻,發(fā)送方的發(fā)送窗口并不總是和接收方的接收窗口一樣大。
因?yàn)榫W(wǎng)絡(luò)具有一定的延時(shí)性。
-
對(duì)于不按序列號(hào)到達(dá)的數(shù)據(jù)應(yīng)該如何處理,TCP并無(wú)明確規(guī)定
- 如果丟棄,雖然實(shí)現(xiàn)更簡(jiǎn)單了,但是會(huì)浪費(fèi)很多網(wǎng)絡(luò)資源。
- 通常存儲(chǔ)在接收窗口中,等到字節(jié)流中所缺少的字節(jié)收到后,再按序號(hào)交付給上層的應(yīng)用進(jìn)程。
-
TCP要求接收方必須有
累積確認(rèn)
和捎帶確認(rèn)機(jī)制
,這樣可以減小傳輸開(kāi)銷(xiāo)。接收方可以在合適的時(shí)候發(fā)送確認(rèn),也可以在自己有數(shù)據(jù)要發(fā)送時(shí)把確認(rèn)信息捎帶上。但是接收方不應(yīng)該過(guò)分推遲發(fā)送確認(rèn)消息,否則會(huì)觸發(fā)超時(shí)重傳浪費(fèi)資源。 -
TCP是全雙工通信
,通信雙方都在發(fā)送和接受報(bào)文段,因此,每一方都有自己的發(fā)送窗口和接收窗口。在談到這些窗口時(shí),一定要區(qū)分開(kāi)。
3.7 TCP超時(shí)重傳
剛才一直再說(shuō)如果有一段報(bào)文遲遲沒(méi)有發(fā)送會(huì)觸發(fā)超時(shí)重傳,但并沒(méi)有說(shuō)如何選擇重傳的時(shí)機(jī),現(xiàn)在就來(lái)說(shuō)說(shuō)TCP對(duì)于超時(shí)重傳的時(shí)機(jī)選擇。
超時(shí)重傳時(shí)間(RTO)
的選擇是計(jì)算機(jī)網(wǎng)絡(luò)最復(fù)雜的問(wèn)題之一。
假如發(fā)送方為A,接收方為B。發(fā)送方A向接收方B發(fā)送數(shù)據(jù)報(bào),并記錄時(shí)間,A收到B的返回的確認(rèn)報(bào)文段后再次記錄時(shí)間。
這兩個(gè)時(shí)間的差值為往返時(shí)間RTT
。如果超時(shí)重傳時(shí)間設(shè)置的比RTT小很多,會(huì)觸發(fā)不必要的重傳。如果設(shè)置的比RTT大很多,遲遲不超時(shí)重傳太影響效率。所以我們要找到一個(gè)正好的時(shí)間,這個(gè)時(shí)間比RTT大一點(diǎn),但大的不多。
??
聽(tīng)起來(lái)很簡(jiǎn)單,但是復(fù)雜的網(wǎng)絡(luò)環(huán)境使傳輸速率復(fù)雜多變,RTT也跟著變化,早上跟晚上的網(wǎng)絡(luò)速率差別都很大。所以超時(shí)重傳時(shí)間(RTO)的選擇是計(jì)算機(jī)網(wǎng)絡(luò)最復(fù)雜的問(wèn)題之一。
這時(shí)候就不能以單次RTT的值確定RTO的值,而是使用很多次RTT的值通過(guò)一定的算法來(lái)計(jì)算出一個(gè)更加合適的RTO。
我們使用RTT代表通過(guò)計(jì)算得出的RTT的值,RTT(i)代表每一次TCP通信產(chǎn)生的RTT值
當(dāng)?shù)谝淮蜶TT產(chǎn)生時(shí),最終RTT的值等于第一次RTT的值。RTT = RTT(1)
RTT多起來(lái)的時(shí)候,使用公式 :
RTT = (1-a)* 上一次RTT + a*RTT(i)
在上式中,0 ≤ a < 1,若a接近于0,則RTT(i)對(duì)RTT的值的影響不大。若a接近于1,則RTT(i)對(duì)RTT的影響較大。標(biāo)準(zhǔn)RFC298建議a的值為1/8
當(dāng)通過(guò)每一次的樣本計(jì)算得出最終RTT后,我們就可以規(guī)定超時(shí)重傳時(shí)間RTO略大于RTT了。
至此,TCP就告一段落了。
4. UDP
由于UDP向應(yīng)用層提供無(wú)連接不可靠的通信服務(wù)
,所以它無(wú)需像TCP那樣實(shí)現(xiàn)流量控制、擁塞控制等等功能,它的字段也十分簡(jiǎn)單。
一個(gè)UDP用戶數(shù)據(jù)報(bào)同樣由首部與數(shù)據(jù)載荷兩部分組成,首部格式如圖所示。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-ATMS6yO6-1678504984189)(assets/image-20230310190305-vf2p1ze.png)]?
它只有四個(gè)字段,每個(gè)字段兩個(gè)字節(jié)共八個(gè)字節(jié)。由于UDP提供無(wú)連接不可靠的服務(wù),所以它只在網(wǎng)際層的基礎(chǔ)上添加了端口號(hào)的區(qū)分。
至此,UDP告一段落。。。才怪,UDP的功能會(huì)在下小節(jié)UDP與TCP的區(qū)別中注明。因?yàn)閷?shí)在太少。。。
5.TCP與UDP的區(qū)別
TCP與UDP所有的區(qū)別都是基于一個(gè)條件 :TCP提供有連接可靠性傳輸服務(wù),UDP提供無(wú)連接不可靠服務(wù)。
如果TCP不提供可靠服務(wù),那他倆就一樣了。
-
TCP傳輸數(shù)據(jù)前需要三報(bào)文握手建立連接,傳輸數(shù)據(jù)結(jié)束時(shí)四報(bào)文揮手?jǐn)嚅_(kāi)連接。
UDP可以隨時(shí)發(fā)送數(shù)據(jù)。只要你知道它的IP就可以突然發(fā)送數(shù)據(jù)。
-
TCP只支持一對(duì)一的solo模式,連接只能在兩個(gè)主機(jī)之間進(jìn)行。
UDP支持單播、多播、廣播。
-
當(dāng)應(yīng)用層報(bào)文發(fā)送到傳輸層時(shí)
TCP將應(yīng)用層傳輸?shù)膱?bào)文拆分為多個(gè)字節(jié)流標(biāo)上序號(hào),再加上TCP首部封裝為T(mén)CP數(shù)據(jù)報(bào),再根據(jù)發(fā)送策略發(fā)送給下層。TCP是面向字節(jié)流的。
UDP僅僅將應(yīng)用層報(bào)文首部添加一個(gè)UDP首部封裝為UDP數(shù)據(jù)報(bào),就將該數(shù)據(jù)報(bào)發(fā)送給接受方。UDP是面向數(shù)據(jù)報(bào)的。
-
如果數(shù)據(jù)傳輸過(guò)程中數(shù)據(jù)丟失、誤碼
TCP會(huì)重新發(fā)送或觸發(fā)重傳機(jī)制。
UDP啥也不干。
最后,對(duì)比一下UDP數(shù)據(jù)報(bào)首部以及TCP數(shù)據(jù)報(bào)的首部格式:
?