一.UDP協議
????????????????UDP是一種無連接、不可靠、面向報文、全雙工傳輸層的協議~
1.無連接 : 知道對端的端口號和IP可以直接傳輸,不需要建立連接
2..不可靠:沒有確認機制,沒有重傳機制,不知道數據包能否能正確到達對端(丟包)!
3.面向數據報:應用層交給UDP多長的報文,UDP原樣發生,既不發生拆分,也不發生合并!
4.全雙工:通信雙方既可以發送數據也可以接受數據~
UDP協議的格式
校驗和:用于保證數據在傳輸過程中沒有被破壞~,但是不能夠確定這個數據100%正確~~
如果校驗和驗證失敗,通常接收端會丟棄這個UDP數據包
UDP的報文是由8字節的報頭和數據的大小~
這個16位UDP長度~~包含報頭和數據~~
理論上這個UDP數據報最大的長度為2^16=65535的字節~~也就越等于64KB~~
那么UDP數據報能傳輸多少數據~
? ? ? ? ? ? ? ? 65535 - 20(IP協議的頭部)- 8(UDP頭部) = 65507字節
因為UDP協議時承載在IP包里的 !
看下圖!👇
二.TCP協議
? ? ? ? ????????TCP是一種有連接、可靠、面向字節流、全雙工的傳輸層的協議
可靠性:不是指的百分百可靠~~有幾率會出錯~
面向字節流:TCP協議將數據視為一個連續的字節流,不關心數據的邊界。接收方只關注字節流的順序和內容,而不關心數據是如何分割成不同的段發送的~~也就是說數據可以被分割成很多份來進行發送
TCP協議的格式
報頭和載荷部分~~
這個TCP協議的格式中的相關內容,我們從講解TCP協議中的相關機制來進行引入~~
序列號
序列號:序列號標識每個字節在數據流中的位置~~用來確保數據正確發送,不會出現錯亂~
以發消息為例~假如你現在正在發送消息。
現在你要給對端發送消息~~.這個消息會以服務器為中介,進而把消息發送到對端~~
但是因為TCP是面向字節流的,而且傳輸路徑也會有差異~所以數據到達對端的時間也會不同~
為了防止其出現錯亂,所以引入了序列號,用來確保數據的正確位置~
確認應答
確認應答是用來確保數據可靠性一種機制
ACK:表示確認號是否有效:0表示無效,1表示有效。此時這里為1
由上述圖可得~~
發送方給接收方發送了1~1000個數據,接收方給發送方返回了ACK,表示1~1000的數據我都接收到了,此時發送方就可以發送1001~2000的數據了~~依次持續!!
超時重傳
超時重傳確保數據可靠性的機制。顧名思義:如果某個數據發生了丟包這種情況,等待了一會,還是沒有這個包,就會發生重傳~~
為什么會發生丟包問題?
在實際的互聯網環境中,鏈路可能擁塞,路由器可能丟包,物理線路也可能出現短暫故障,導致數據丟失~
1.發送方發生丟包問題~~
2.接收方返回ack時發生丟包問題~~
這張圖,你是不是發現了一個問題~~主機B收到了兩次1-1000的數據包~~這就有問題了~~
例如:這場景如果發生在扣款的過程中,如果已經了扣了一次款,但沒有接收到應答~,就又扣了一次款~你的錢包就會默默得少了~~哈哈
看下圖~~
注意:接收緩沖區不僅可以進行去重,也可以進行排序~~
那么超時重傳的時間應該如何確定~~
如果超時時間設得太長~會影響整體得重傳效率~~如果超時時間設置的太短,又可能會頻繁發送重復的包~~所以我們需要確保重傳的時間~~
TCP為了保證效能~~會動態地計算這個最大超時時間~~
在Linux中,超時以500ms為一個單位來進行控制~~,每次判定地超時時間都是500ms地整數倍~~如果重發一次之后,接收不到應答~~會等待2*500ms來進行重傳~~此時,還沒又接收到應答~·等待4*500ms進行重傳~~依次類推~~如果仍然接收不到~~TCP會強制關閉連接~~
連接管理
1.三次握手(建立連接)
三此握手的意義
1.三次握手,可以針對通信路徑,進行投石問路~~初步的確認一下通信鏈路是否
暢通~~
2.三次握手,也在驗證通信雙方,發送能力和接收能力是否正確~~
3.三次握手在過程中也會協商一些必要的參數~~例如:初始序列號、窗口大小、MSS(控制報文中的最大長度)
2.四次揮手(斷開連接)
這次以客戶端為例,服務器也可以進行斷開連接~~
客戶端給服務器發送fin表示數據發送完了,我想斷開連接~
服務器接收到之后,給客戶端返回ack
服務器給客戶端發送fin ,表示我這幫也處理完了,可以斷開連接~~
客戶端給服務器返回ack,服務器接收到之后,成功斷開連接~~
你們是不是有個問題~~中間的fin和ack能不能合并成一條~~直接發送給客戶端
被動斷開連接的中仍然需要一些時間繼續發送未完成的數據~~
所以ack和fin中有時間間隔~~不能簡單合并~~
如果說服務器掛了,也可以觸發四次揮手~~
滑動窗口
滑動窗口是來優化TCP協議傳輸數據的效率~~如果像之前一樣你每發送1字節的數據,都需要ack,依次往后推!這樣效率就會太慢了~~所以引入了滑動窗口的機制~
滑動窗口~
是通過批量傳輸~~,現在先發一個數據,不等ack,再發下一個,繼續往下發,連續發送了一定的數據之后統一等一波ack~~
如果出現了丟包情況~~應該怎么處理?
接收方出現丟包~~
發送方發生丟包~~
假如說1~1000的數據發生了丟包~~主機B給A返回的ack就一直是0,但同時主機B記錄著后序的數據包的序號,只要主機A重傳之后丟失的數據包~~,主機B便會返回ack就是主機A上一個序號+1
流量控制
接收端處理數據的速度是有限的,如果發送端數據發送的過快,導致接受端的緩沖區被打滿,這個時候如果發送端繼續發送,就會造成丟包~繼而會引起丟重傳等一系列的連鎖反應
所以引入流量控制的機制~~
接受端將自己可以接收的緩沖區大小放入TCP首部中的“窗口大小”字段,通過ACK端通知發送端~~
窗口大小字段越大,說明網絡的吞吐量越高~~
接收端一旦發現自己的緩沖區塊滿了,就會將窗口大小設置成一個更小的值通知給發送端~
發送端接收到這個窗口之后,就會減慢自己的發送速度~
如果接收緩沖區滿了,就會將窗口設置為0;這時發送方不再發送數據,但是需要定期發送一個窗口探測數據段,使接受端把窗口大小告訴對端~~
擁塞控制
擁塞控制是指:防止網絡中的數據太多,造成網絡鏈路擁堵,從而導致整體通信性能下降的一套機制~~
1.TCP中引入慢啟動機制,剛開始窗口的大小是0,先發少量的數據~~如果傳輸的數據,沒有出現丟包~然后就要增大窗口大小~~增大方式是按照指數來增長~~
2.指數增長,不會一直持續保持的~~可能會增長太快~,一下子就導致
網絡擁堵~~引入一個閾值之后,指數增長就變成了線性增長~
3.線性增長也是一直再增長,積累一段時間之后,傳輸的速度可能過快~~從而導致了丟包~~就會觸發快速重傳~~進行乘法減少~~這里假設設置直接減少為原來一般~~
4.然后進入恢復階段,繼續線性增長~~
?我所說的就是如下圖👇!!
延遲應答
如果接收數據的主機立刻返回ACK應答,這時候返回的窗口可能比較小~~
所以要對ACK進行延遲,從而增大窗口大小,進而提升了數據傳輸的效率~~
如下圖
下圖就體現了延遲應答的機制~~
捎帶應答
?捎帶應答:是指在發送方向接收方發送數據時,順便把對接收方上一份數據的確認(ACK)信息一起帶上發送,而不是單獨發送確認~
假設A向B發送數據~~B收到后需要發送ACK確認~~如果B也正好要向A發送數據,那么它可以把ACK捎帶在自己的數據包中一起發出去,這樣就避免了單獨發送ACK的額外開銷~~
這樣可以提升傳輸效率~~
粘包問題
在使用TCP協議來進行數據傳輸時,接收方一次性讀取了多個發送方發送的數據包,導致多個消息粘連在一起,邊界不清楚的現象
??
如何處理粘包問題~~
1.定長消息
每個消息固定長度,接收方按長度讀取~~
2.特殊分隔符~
使用特定字符(\n,\0)來標識信息結束
3.消息頭加長度字段~~
在每個消息前加上表示長度的字段~~
異常情況
(1).其中一方發生了進程崩潰~~
進程無論時正常就結束,還時異常崩潰,都會觸發回收文件資源~也就會觸發四次揮手~~
因為TCP連接的生命周期,比進程更長一些。雖然進程已經退出,但是TCP連接還在,仍然可以觸發四次揮手~~
(2).其中有一方出現關機
當有個主機,觸發關機操作,就會先強制終止所有的進程~~終止進程自然就會觸發4次揮手~~
注意:如果揮的不快,至少也能把第一個fin發給對端~~對端接收帶fin之后,就要向對方發送ack
但是因為對方關機了,就會觸發超時重傳的機制~當重傳幾次之后,自然會斷開連接~~
(3).其中一方出現了斷電~
如果說斷電的是接收方~~發送方就會突然發現沒有ack了,就要重傳~
重傳了幾次之后還是不行~~
TCP就會嘗試“復位(RST)”連接,相當于清楚原來的TCP中的各種臨時書庫~重新開始~此時的
RST網頁不會有ack,重置了還不行,單方面放棄連接~
如果說斷電的是發送方??接收方本來也就在阻塞等待?結果遲遲每來消息~
怎么辦?這個情況下,接收方需要區分出,是發送方掛了,還是好著內但是沒有發送消息~
如果接收方等待了一段時間之后,沒有收到對方的消息,就會吃醋發“心跳包”來詢問對方的情況~~如果多次心跳包沒有響應,則認為對端掛了~~
總結:
?如果有相關的問題,大佬可以指證下~~文章有錯誤,在所難免~~