1. 程式人生 > 實用技巧 >傳輸層協議--->UDP/TCP,

傳輸層協議--->UDP/TCP,

傳輸層>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

UDP

協議端格式
在這裡插入圖片描述

  • UDP報頭8byte,其中有16位的UDP長度,也就是說UDP最大長度為64KB

無連線,不可靠,面向資料報。

  • 無連線: 知道目標的IP和目標埠號就直接進行傳輸, 不需要建立連線;
  • 不可靠: 沒有確認機制, 沒有重傳機制; 如果因為網路故障該段無法發到對方, UDP協議層也不會給應用層返回任何錯誤資訊;
  • 面向資料報: 不能夠靈活的控制讀寫資料的次數和數量;應用層交給UDP多長的報文, UDP原樣傳送, 既不會拆分, 也不會合並。
    注意:UDP能傳輸的資料最大長度是64K(包含UDP首部8byte),如果我們需要傳輸的資料超過64K, 就需要在應用層手動的分包, 多次傳送, 並在接收端手動拼裝。

TCP(傳輸控制協議)

在這裡插入圖片描述

  • 4位報首長度:報首有多少個32位bit(4位元組),TCP報首最大長度為15*4=0;

  • 標誌位:URG-緊急指標是否有效;ACK-確認號是否有效;PSH-提示接收端立即從緩衝區將TCP資料讀出;RST-重新建立連線標誌位復位報文段;SYN-請求建立連線同步報文段;FIN-通知對方,本端關閉結束報文段

  • TCP 是面向位元組流的,通過 TCP 傳送的位元組流中的每個位元組都按順序編號,而報頭中的序號欄位值則指的是本報文段資料的第一個字的序號。

確認應答(ACK)機制

  • TCP將每個位元組的資料都進行了編號. 即為序列號.每一個ACK都帶有對應的確認序列號, 意思是告訴傳送者, 我已經收到了哪些資料; 下一次你從哪裡開始發.

超時重傳機制

  • 主機A傳送資料給B之後, 可能因為網路擁堵等原因, 資料無法到達主機B;如果主機A在一個特定時間間隔內沒有收到B發來的確認應答, 就會進行重發;
    超時以500ms為一個單位進行控制, 每次判定超時重發的超時時間都是500ms的整數倍.如果重發一次之後, 仍然得不到應答, 等待 2500ms 後再進行重傳.如果仍然得不到應答, 等待 4500ms 進行重傳. 依次類推, 以指數形式遞增.累計到一定的重傳次數, TCP認為網路或者對端主機出現異常, 強制關閉連線。

補充:主機A未收到B發來的確認應答,若是因為ACK丟失,主機B會收到很多重複資料. 那麼TCP協議利用前面提到的序列號能夠識別出那些包是重複的包, 並且把重複的丟棄掉,做到去重的效果。

連線管理機制

  • 在正常情況下, TCP要經過三次握手建立連線, 四次揮手斷開連線。
    在這裡插入圖片描述在這裡插入圖片描述
TIME_WAIT狀態(請求方)

TCP協議規定,主動關閉連線的一方要處於TIME_ WAIT狀態,等待兩個MSL(maximum segment lifetime)的時間後才能回到CLOSED狀態。
MSL是TCP報文的最大生存時間, 因此TIME_WAIT持續存在2MSL的話就能保證在兩個傳輸方向上的尚未被接收或遲到的報文段都已經消失同時也是在理論上保證最後一個報文可靠到達。

CLOSE_WAIT 狀態(接收方)

進入CLOSE_WAIT後說明被動方準備關閉連線(需要處理完之前的資料); 當被動方真正呼叫close關閉連線時, 會向主動方傳送FIN, 此時被動方進入LAST_ACK狀態, 等待最後一個ACK到來(這個ACK是主動方確認收到了FIN)。

滑動視窗

起因:每一個傳送的資料段, 都要給一個ACK確認應答. 收到ACK後再發送下一個資料段,這樣做有一個比較大的缺點, 就是效能較差. 尤其是資料往返的時間較長的時候。

  • 那麼一次傳送多條資料, 就可以大大的提高效能(其實是將多個段的等待時間重疊在一起了),這便是滑動視窗。

補充:視窗大小指的是無需等待確認應答而可以繼續傳送資料的最大值. 若視窗大小是4000個位元組(四個段).傳送前四個段的時候, 不需要等待任何ACK, 直接傳送;收到第一個ACK後, 滑動視窗向後移動, 繼續傳送第五個段的資料; 依次類推;作業系統核心為了維護這個滑動視窗, 需要開闢傳送緩衝區來記錄當前還有哪些資料沒有應答; 只有確認應答過的資料, 才能從緩衝區刪掉;視窗越, 則網路的吞吐率就越;
若傳送失敗,利用開闢的緩衝區可以實現"高速重發控制"(也叫 “快重傳”).

流量控制

  • 接收端處理資料的速度是有限的. 如果傳送端發的太快, 導致接收端的緩衝區被打滿, 這個時候如果傳送端繼續傳送,就會造成丟包, 繼而引起丟包重傳等等一系列連鎖反應.因此TCP支援根據接收端的處理能力, 來控制傳送端的傳送速度. 這個機制就叫做流量控制(Flow Control);

補充:接收端將自己可以接收的緩衝區大小放入TCP首部中的 “視窗大小” 欄位, 通過ACK端通知傳送端;視窗大小欄位越大, 說明網路的吞吐量越高;接收端一旦發現自己的緩衝區快滿了, 就會將視窗大小設定成一個更小的值通知給傳送端;傳送端接受到這個視窗之後, 就會減慢自己的傳送速度;如果接收端緩衝區滿了, 就會將視窗置為0; 這時傳送方不再發送資料, 但是需要定期傳送一個視窗探測資料段, 使接收端把視窗大小告訴傳送端.

擁塞控制

起因:雖然TCP有了滑動視窗這個大殺器, 能夠高效可靠的傳送大量的資料. 但是如果在剛開始階段就傳送大量的資料, 仍然可能引發問題.因為網路上有很多的計算機, 可能當前的網路狀態就已經比較擁堵. 在不清楚當前網路狀態下, 貿然傳送大量的資料,
是很有可能引起雪上加霜的.

  • TCP引入慢啟動機制, 先發少量的資料, 探探路, 摸清當前的網路擁堵狀態, 再決定按照多大的速度傳輸資料;

補充:擁塞視窗增長速度, 是指數級別的. “慢啟動” 只是指初使時慢, 但是增長速度非常快,為了不增長的那麼快, 因此不能使擁塞視窗單純的加倍.此處引入一個叫做慢啟動的閾值當擁塞視窗超過這個閾值的時候, 不再按照指數方式增長, 而是按照線性方式增長,當網路擁塞時乘法減小

擁塞控制, 歸根結底是TCP協議想盡可能快的把資料傳輸給對方, 但是又要避免給網路造成太大壓力的折中方案。

延時應答

  • 延遲一會,等待快取區中資料被處理,那麼剩餘的快取區就會大些,這就是延時應答。

解釋:假設接收端快取區大小為1M,一次接收到了500K的資料,現在快取區中剩餘大小為500。但如果我們延時一段時間,等待接受方處理了該快取區中的資料,那麼我們的剩餘大小就為1M了(即:視窗大小)。

補充:1.等待的時間每個作業系統中設定的等待時間是不一樣的。(200ms)
2.數量限制:每隔兩個包就應答一次 。
3.時間限制:超過最大延時時間就應答一次(200ms)

捎帶響應

  • 在延時應答的基礎上,我們發現,接受方和傳送方都是“一發一收”,所以,伺服器在傳送資料的時候,我們把ACK搭順風車的方式傳送給對方了

小結

可靠性:
校驗和,序列號(按序到達),確認應答,超時重發,連線管理,流量控制,擁塞控制
提高效能:
滑動視窗,快速重傳,延遲應答,捎帶應答
其他:
定時器(超時重傳定時器, 保活定時器, TIME_WAIT定時器等)

TCP/UDP對比

TCP用於可靠傳輸的情況, 應用於檔案傳輸, 重要狀態更新等場景;
UDP用於對高速傳輸和實時性要求較高的通訊領域, 例如, 早期的QQ, 視訊傳輸等. 另外UDP可以用於廣播。

粘包問題

TCP粘包是指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收緩衝區看,後一包資料的頭緊接著前一包資料的尾。

出現粘包現象的原因是多方面的,它既可能由傳送方造成,也可能由接收方造成。傳送方引起的粘包是由TCP協議本身造成的,TCP為提高傳輸效率,傳送方往往要收集到足夠多的資料後才傳送一包資料。若連續幾次傳送的資料都很少,通常TCP會根據優化演算法把這些資料合成一包後一次傳送出去,這樣接收方就收到了粘包資料。接收方引起的粘包是由於接收方使用者程序不及時接收資料,從而導致粘包現象。這是因為接收方先把收到的資料放在系統接收緩衝區,使用者程序從該緩衝區取資料,若下一包資料到達時前一包資料尚未被使用者程序取走,則下一包資料放到系統接收緩衝區時就接到前一包資料之後,而使用者程序根據預先設定的緩衝區大小從系統接收緩衝區取資料,這樣就一次取到了多包資料
UDP的時候, 要麼收到完整的UDP報文, 要麼不收,所以不存在粘包問題

粘包問題的解決
明確兩個包之間的邊界

對於定長的包, 保證每次都按固定大小讀取即可; 例如上面的Request結構, 是固定大小的, 那麼就從緩衝區從頭開始按sizeof(Request)依次讀取即可;
對於變長的包, 可以在包頭的位置, 約定一個包總長度的欄位, 從而就知道了包的結束位置;
對於變長的包, 還可以在包和包之間使用明確的分隔符(應用層協議, 是程式猿自己來定的, 只要保證分隔
符不和正文衝突即可);