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