1. 程式人生 > >傳輸層(Udp協議 Tcp協議)

傳輸層(Udp協議 Tcp協議)

傳輸層是負責資料能夠從傳送端傳輸接收端。負責端與端之間的傳輸。端與端就相當於是兩個程序之間的資料傳輸。
埠號
埠號是傳輸層協議的內容:
埠號是一個2位元組16位的無符號整數;(0-65535之間一個數字,0-1023不推薦使用)
埠號用來標識一個程序,告訴作業系統,當前資料要交給哪一個程序來處理。(為什麼不用pid=getpid()來標識一個程序,因為pid會變,如一個程序關閉再開啟後,pid就會變,而一個程序的埠號不會變)
IP地址+埠號能夠唯一標識網路上某一主機的某一程序;
在TCP/IP協議中, ⽤ “源IP”, “源端⼝號”, “⺫的IP”, “⺫的端⼝號”, “協議號” 這樣⼀個五元組來標識⼀個通訊(可以通過netstat -n檢視);
埠號範圍劃分:0-2013 :知名埠號
ssh伺服器 :22 埠
ftp伺服器: 21埠
telnet伺服器: 23埠
http伺服器 : 80埠
https伺服器:443埠
執行 cat /etc/services可以看到知名埠號:
在這裡插入圖片描述


netstat

netstat:
語法:netstat [選項]
功能:檢視網路狀態
常用選項:
n :拒接顯示別名,能顯示數字的全部轉化為數字
l  :僅列出有在listen(監聽)的符狀態
p :顯示建立相關連結的程式名
t  :(tcp)僅顯示tcp相關選項
u :  (udp)  僅顯示udp相關選項
a: (all)  顯示所有選項,預設不顯示LISTEN相關

Udp協議
UDP協議端格式(UDP資料結構):
在這裡插入圖片描述
注:UDP頭資訊是8個位元組;
UDP協議⾸部中有⼀個16位的最⼤⻓度. 也就是說⼀個UDP能傳輸的資料最⼤⻓度是65535即64K(包含UDP⾸部). (1k=1024位元組,2^10=1024, 2 ^16=2 ^ 6 *1K),那麼資料最大長度是64K(65535)-8;
如果我們需要傳輸的資料超過64K, 就需要在應⽤層⼿動的分包, 多次傳送, 並在接收端⼿動拼裝;但是就不會保證有序,需要使用者在應用層進行排序(編號)。
如果校驗出錯,就會直接丟棄。
Udp特點:


1.無連線:知道對端的ip和埠號就直接進行傳輸,不需要建立連線;
2.不可靠:沒有確認機制,沒有重傳機制,如果因為網路故障該段無法發到對方,udp協議層不會給應用層返回任何錯誤資訊。
3.面向資料報:不能靈活的控制讀寫資料的次數和數量。
應⽤層交給UDP多⻓的報⽂, UDP原樣傳送, 既不會拆分, 也不會合並:如果傳送端調⽤⼀次sendto, 傳送100個位元組, 那麼接收端也必須調⽤對應的⼀次recvfrom, 接收100
個位元組; ⽽不能迴圈調⽤10次recvfrom, 每次接收10個位元組;
資料必須一整條傳送或接受,不能拆分或者合併原因如下:
因為在udp頭中定義了udp資料報長度,那麼資料長度就國定,每一條資料都是按照這個長度進行傳送或接受,這個特點有一個優點是不會造成粘包問題。
Udp緩衝區:

UDP沒有真正意義上的 傳送緩衝區. 調⽤sendto會直接交給核心, 由核心將資料傳給網路層協議進⾏後續的傳輸動作;
UDP具有接收緩衝區. 但是這個接收緩衝區不能保證收到的UDP報的順序和傳送UDP報的順序⼀致; 如果緩衝區滿了, 再到達的UDP資料就會被丟棄;
UDP的socket既能讀, 也能寫, 這個概念叫做 全雙⼯。
UDP傳輸優點:不會造成粘包問題,另外傳輸速度快(沒有連線管理機制和可靠傳輸機制)
Tcp協議
TCP協議格式:
在這裡插入圖片描述
注:1.4位TCP報頭⻓度: 表⽰該TCP頭部有多少個32位bit(有多少個4位元組); 所以TCP頭部最⼤⻓度是15 * 4 = 60 ;
2. 6位標誌位:
URG: 緊急指標是否有效
ACK: 確認號是否有效
PSH: 提⽰接收端應⽤程式⽴刻從TCP緩衝區把資料讀⾛
RST: 對⽅要求重新建⽴連線; 我們把攜帶RST標識的稱為復位報⽂段
SYN: 請求建⽴連線; 我們把攜帶SYN標識的稱為同步報⽂段
FIN: 通知對⽅, 本端要關閉了, 我們稱攜帶FIN標識的為結束報⽂段
16位校驗和: 傳送端填充, CRC校驗. 接收端校驗不通過, 則認為資料有問題. 此處的檢驗和不光包含TCP⾸部, 也包含TCP資料部分.
16位緊急指標: 標識哪部分資料是緊急資料;
16位窗⼝⼤⼩:指的是⽆需等待確認應答⽽可以繼續傳送資料的最⼤值
tcp是有連線可靠面向位元組流傳輸。
連線管理機制:
可以檢視這篇部落格:https://blog.csdn.net/sophia__yu/article/details/82932194
可靠傳輸機制
1.確認應答機制:傳送的每條資料都需要確認回覆一下。
2.超時重傳機制:傳送方等待一段時間後還沒有收到回覆,就認為傳輸失敗,將資料重傳。這個超時時間是遞增的,並且次數是有限制的,超過最大次數就認為網路斷開。
3.重傳有序: 重新傳輸可能會造成包的無序(後傳送的資料可能會先到,先發的資料可能後到),序號和確認序號保證重新傳輸有序。
保證有序:序號按位元組排序,傳送的資料是1000位元組,兩者之間相互協商後加入把起始位置設為1,那麼資料序號就是1-1000,當把資料傳送 過去後,對端看到是1000個位元組,而且起始序號是1,就認為是成功接收,然後回覆1001,1001代表成功接收,並且接下來接收的資料序號從1001開始。如果先接受1001-2000序號資料,,會把這個資料放到緩衝區的1001-2000,前面的1-1000會空著。

tcp因為要保證可靠傳輸,導致效能有很大的消耗,為了提高tcp傳輸效能,需要一些其他的機制。
滑動視窗機制
剛討論的確認應答策略, 對每⼀個傳送的資料段, 都要給⼀個ACK確認應答. 收到ACK後再發送下⼀個數據段. 這樣做有⼀個⽐較⼤的缺點, 就是效能較差. 尤其是資料往返的時間較⻓的時候.而滑動視窗機制是一次發生多條資料,集中等待(快速重傳)
在tcp頭中有16位視窗大小:指的是⽆需等待確認應答⽽可以繼續傳送資料的最⼤值。
視窗越大,網路的吞吐量越大。

  • 如果發生方沒有接受到第一條資料的ack回覆,但是接受到第二條資料的ack,那麼它認為第一條資料也傳送成功,不需要重傳,這樣就會提高效能;
  • 如果傳送方的資料沒有成功傳送(丟了),那麼 接收方會連續三次ack說要的是第一條資料,但是並不會傳送第二條已經接受到的ack,傳送方收到三次(三次是因為有可能網路較慢,需要確定資料是否真的丟了。)ack請求就會進行資料重傳。
    一次傳送的資料有多少取決於tcp協議中視窗大小欄位----視窗大小在進行資料傳輸前會進行雙方協商。這個視窗大小不會超過接收方接收緩衝區大小。
    流量控制:
  • 為什麼出現流量控制: 接收端處理資料的速度是有限的. 如果傳送端發的太快, 導致接收端的緩衝區被打滿, 這個時候如果傳送端繼續傳送, 就會造成丟包, 繼⽽引起丟包重傳等等⼀系列連鎖反應.因此TCP⽀持根據接收端的處理能⼒, 來決定傳送端的傳送速度. 即依靠流量控制。
  • 通過不斷的重新設定視窗大小,來告訴對方我能一次接收多少資料,最終達到一個流量控制的效果,避免因為傳送太快,而處理太慢,導致接收方緩衝區塞滿引起的大量丟包重傳(當塞滿後,會把緩衝區大小設為0,那麼就不會再發送資料,當緩衝區空了後,會再次設定緩衝區大小進行資料傳輸)

擁塞控制

  • 為什麼出現擁塞控制:雖然TCP有了滑動窗⼝這個⼤殺器, 能夠⾼效可靠的傳送⼤量的資料. 但是如果在剛開始階段就傳送⼤量的資料,如果出現丟包,重傳會使效能下降。

  • 如何做:TCP引⼊ 慢啟動 機制, 先發少量的資料, 探探路, 摸清當前網路擁堵狀態, 再決定按照多⼤的速度傳輸資料;
    一開始將擁塞視窗設定為1,當傳送第一個資料收到ack後,認為網路比較好,第二次就會發生2個包,再次收到ack,第三次就會發生4個包,即傳送包的數量按照質數增長。但是每傳送資料包的時候,會將擁塞視窗和和接收端主機反饋的窗⼝⼤⼩做⽐較, 取較⼩的值作為實際傳送大小,即擁塞視窗控制著tcp傳輸的慢啟動;當然也不能一直增長,增長到閾值(協商視窗大小)後,傳送資料速度變慢;

  • 在每次超時重發的時候,閾值會變成原來的⼀半, 同時擁塞窗⼝置回1;

  • 當TCP通訊開始後, 網路吞吐量會逐漸上升; 隨著網路發⽣擁堵, 吞吐量會⽴刻下降;

  • 擁塞視窗避免網路不好,導致丟包重傳。總之,擁塞視窗是想盡一切辦法將資料傳輸給對方。
    延時應答
    假設接收端緩衝區為1M. ⼀次收到了500K的資料; 如果⽴刻應答, 返回的窗⼝就是500K;但實際上可能處理端處理的速度很快, 10ms之內就把500K資料從緩衝區消費掉了;在這種情況下, 接收端處理還遠沒有達到⾃⼰的極限, 即使窗⼝再放⼤⼀些, 也能處理過來;如果接收端稍微等⼀會再應答, ⽐如等待200ms再應答, 那麼這個時候返回的窗⼝⼤⼩就是1M;

  • 窗⼝越⼤, 網路吞吐量就越⼤, 傳輸效率就越⾼. 在保證網路不擁塞的情況下儘量提高傳輸效率;

  • 接收方對接受到的資料能夠快速處理,只要稍微延時一下進行ack回覆,那麼能夠設定的視窗大小就會盡可能的大,一直保證一個tcp的最大吞吐量。假如是立即應答,那麼有可能回覆的這個視窗就比較小。

  • 並不是所有包都可以延遲應答:數量限制:每隔N個包就應答一次;時間限制:超過最大延遲應答一次。
    捎帶應答機制:
    將確認應答直接標記在即將發生的資料包內,那麼這樣不僅傳輸了資料還對上一次接受的資料進行應答(少傳輸一個應答包)
    面向位元組流

  • 什麼是面向位元組流: 由於緩衝區的存在, TCP程式的讀和寫不需要⼀⼀匹配, 例如:
    寫100個位元組資料時, 可以調⽤⼀次write寫100個位元組, 也可以調⽤100次write, 每次寫⼀個位元組;讀100個位元組資料時, 也完全不需要考慮寫的時候是怎麼寫的, 既可以⼀次read 100個位元組, 也可以⼀次read⼀個位元組, 重複100次;

  • 粘包問題:如果傳送的位元組數太短, 就會先在緩衝區⾥等待, 等到緩衝區長度差不多或者實際差不多將資料傳送資料,那麼就不清楚資料的邊界,造成資料粘包問題。Udp不會造成粘包問你題,是因為UD頭部中有資料報長度,那就可以計算出資料長度,有了資料長度,通過資料長度來找資料的邊界,就不會造成粘包問題。

  • 傳送緩衝區和接受緩衝區都有可能出現粘包問題:
    傳送端:為了提高傳輸效能,因此將多個小包合到一塊進行傳送(但是也可以設定套接字,一次傳送多少 )
    接受端:將接受的資料放到接受緩衝區,如果處理慢,導致資料在緩衝區淤積合併

  • 如何避免粘包問題:資料定長,特殊字元間隔(只要保證分隔符和正文字元不衝突即可),tlv格式資料( 可以在包頭的位置, 約定⼀個包總⻓度的欄位, 從⽽就知道了包的結束位置)。
    Tcp的可靠性依靠下列:

  • 校驗和:保證資料的準確性;

  • 序列號:保證按序到達;

  • 確認應答和超時重發:保證資料到達;

  • 連線管理:保證兩段建立起連線;
    提高Tcp效能

  • 滑動視窗:一次發多條資料,集中等待回覆;

  • 快速重傳

  • 延遲應答:稍等一會兒時間回覆,提高吞吐量;

  • 捎帶應答:確認應答直接標記在即將發生的資料包內;

  • 流量控制: 不斷重新設定視窗大小,避免大量丟包重傳導致效能下降;

  • 擁塞控制:慢啟動,快增大,儘可能使資料傳輸給對方;
    Udp和Tcp誰更優?
    TCP是可靠連線, 那麼是不是TCP⼀定就優於UDP呢? TCP和UDP之間的優點和缺點, 不能簡單, 絕對的進⾏⽐較。tcp和udp根據自己的特點應用於不同的場景:
    TCP:⽤於可靠傳輸的情況, 應⽤於⽂件傳輸, 重要狀態更新等場景;
    UDP:⽤於對⾼速傳輸和實時性要求較⾼的通訊領域, 例如, 早期的QQ, 視訊傳輸等. 另外UDP可以⽤於廣播。
    用Udp實現可靠傳輸
    參考TCP的可靠性機制, 在應⽤層實現類似的邏輯:
    引⼊序列號, 保證資料順序;
    引⼊確認應答, 確保對端收到了資料;
    引⼊超時重傳, 如果隔⼀段時間沒有應答, 就重發資料…