1. 程式人生 > >計算機網路_UDP程式設計流程&TCP和UDP區別

計算機網路_UDP程式設計流程&TCP和UDP區別

一、 流程

1.1 伺服器端

int socket(int domain,  int type,  int pro);  //步驟一、生成套接字

int bind(int sockfd,  struct sockaddr* seraddr, int size);  //步驟二、繫結套接字和地址

int recvfrom(int sockfd, void *buff, int size, int flag, //步驟三、將客戶端發來的訊息讀入buf

                   struct sockaddr*cliaddr, int *

addrlen);  //用於回覆訊息, addrlen需要在函式內改變,配合sendto

int sendto(int sockfd, void* buf, int datalen, int flag, //步驟四、伺服器向客戶端傳送訊息,形成資訊的互動

                   struct sockaddr* cliaddr, int addrlen); //用於傳送訊息,addrlen是明確的,不會在函式內改變。

int close(int sockfd); //步驟五

、關閉套接字

1.2 客戶端

int socket(int domain, int type, int pro); //步驟一、 生成套接字

int recvfrom(int sockfd, void *buf, int size, int flag,  //步驟二、接收訊息

                   struct sockaddr *cliaddr, int *addrlen);

int sendto(int sockfd, void *buf, int datalen, int flag, //步驟三

、傳送訊息,形成資訊的互動

                   struct sockaddr *cliaddr, int addrlen);

int close(int sockfd); //步驟四、關閉套接字

二、 TCP原理 

2.1 位元組流服務

圖1 TCP工作流程

傳送資料的次數和接受資料的次數無關,底層資料傳送和接收時,資料有可能會被分開或者合併。 那麼如何保證資料是有序的呢?

圖2 TCP報頭結構

從圖2 直觀可以看到明確有5行,每行4byte,TCP報頭大小至少是20byte;選項是40byte,TCP報頭大小∈[20, 60],我們不妨只關注前20byte。 迴歸主題,到底是如何保證資料是有序的呢?

圖3 序號欄位示意圖

如圖3 所示,假設傳送的第一個TCP報文的序號是2000,資料量是30byte;那麼第二個TCP報文的序號就是2030,以此類推。當接收端收到這4個報文時,接收順序與傳送順序沒有直接關係,雖然是按照1 2 3 4的順序去傳送,但這不能保證會按照1 2 3 4的順序來接收,接收順序取決於網路環境等諸多因素,是未知的。但是我把接收到的報文按照SYN從小到大的順序去讀取,就能保證和原發送順序一致了。 

2.2 接收&傳送緩衝區

序號欄位一定程度上保證了接收順序和傳送順序一致,而緩衝區的存在則可以暫時儲存資料。TCP協議還有一個神奇之處在於,接收端會檢查緩衝區的大小,然後讓傳送端知道這件事情。傳送端見到接收端緩衝區快滿了,就會慢點發送資料,見到接收端緩衝區比較空閒,傳送資料的資料就快些。

圖4 TCP流量控制模型

A、B都是水池:水不管在哪裡溢位都是浪費

  • A或B水池將滿, 水龍頭水量減少;

  • 反之也成立;

 2.3 可靠性評價

  • 前提:所有的資料都能到達對端    <------確認機制和超時重傳機制(緩衝區)。
  • 資料不亂序   <------TCP報頭中的序號,也可以用於處理重複報文段,如果兩個報文序號一致,丟棄一個。
  • 資料不出錯   <------16位的校驗和欄位。

三、 UDP原理

3.1 資料報服務

傳送次數和接收次數相等,要麼不讀取,要麼一次將資料讀取完,否則UDP報文段資料丟失。必須一次性將整個UDP報文讀取完

圖5 UDP工作流程

 3.2 可靠性評價

圖6 UDP報頭結構
  • 前提:所有的資料都能到達對端  <------無法保證:沒有傳送緩衝區,資料發出去是沒有備份的。
  • 資料不亂序 <------無法保證:主要是聽天由命,看哪個UDP報文段先到達對端。
  • 資料不出錯 <------校驗和欄位可以保證。

四、 速度比較

4.1 MTU

最大傳輸單元(Maximum Transmission Unit,MTU)是指一種通訊協議的某一層上面所能通過的最大資料包大小(以位元組為單位)。最大傳輸單元這個引數通常與通訊介面有關(網路介面卡、串列埠等)。

4.2 三種時延

圖7 時延
  • 傳送時延 = 資料塊大小/通道頻寬。

  • 等待時延:資料排隊所經過的延時。

  • 傳輸時延:通道長度/傳輸速率 ------客觀因素:在技術沒有明顯提升的前提下,不可改變。

等待時延,就以在銀行視窗辦理業務來理解吧。假設有一天,我去銀行辦理業務,來的比較晚;排在了隊伍的最後面(把插隊的情況排除)。問:什麼時候輪到我?這由兩個因素決定:1 前面有多少人; 2 具體到每個人辦理業務的時間。最極端的情況,我前面雖然只有1個人,但是那個人正在辦理一項很重要的業務,耗時較長,能說隊伍短我等待的時間一定短嗎?再比如說,雖然我前面有5個人,但他們都只辦理查詢業務(這個是很快的),我排在5個人的隊伍後面沒準會比排在1個人的隊伍後面等待時間更短啊,所以,單憑隊伍長短來斷定我等待辦理業務的時間是不盡合理的。

之所以會提到這個,是為了引出稍後會提到:MTU增加,傳送相同資料的包個數減少,也就是隊伍長度縮短,能說MTU增加一定能將等待時延降下來嗎?不能,因為處理每個包的時間可能會變長,但也只是可能而已。類似於雖然隊伍縮短了,但是辦理業務的人很磨蹭,等待時間可能並不會減少。

下面再舉一個高速公路上運送貨物的例子。在這裡,貨物就是有用的資料:

圖8 6車道運送貨物示意圖

對於單件貨物來說,先放在等待佇列裡,輪到它的時候浪費的時間稱為等待時延,假設每輛貨車載貨量是100單位,但是待發送貨物一共701單位,簡單理解:第一輪先派出6輛車運送,第二輪派出1輛車運送,從貨物準備傳送到貨物全部發送出去的時間點為止經歷的時間稱為傳送時延,傳輸時延很好理解,不作類比了。

結合MTU來看看三種時延吧:乙太網的MTU值是1500 bytes,假設傳送者的協議高層向IP層傳送了長度為3008 bytes的資料報文,則該報文在新增20 bytes的IP包頭後IP包的總長度是 3028 bytes,因為3028 > 1500,所以該資料報文將被分片,

分片時僅僅對上層的資料進行分片,不需要對原來的IP首部分片,所以要分片的資料長度只有3008,而不是3028。

分片過程如下:

  1. 首先計算最大的IP包中IP淨荷的長度 =MTU-IP包頭長度=1500-20= 1480 bytes。
  2. 然後把3008 bytes按照1480 bytes的長度分片,將要分為3片,3008= 1480+1480+48。
  3. 最後傳送者將為3個分片分別新增IP包頭,組成3個IP包後再發送,3個IP包的長度分別為1500、1500、68 bytes。

將MTU和時延結合起來理解一下吧: 

  • MTU越大,傳送相同的使用者資料所需的資料包個數也越低;
  • 但是MTU增大會增加傳送時延,並且MTU越大,資料包中 bit位發生錯誤的概率也越大。

最終目標是將總時延降下來,所以MTU要選擇一個合適的值。

總而言之:UDP是會比TCP快的。