TCP/IP和UDP的區別之二


1、傳輸層存在的必要性

       由於網絡層的分組傳輸是不可靠的,無法瞭解數據到達終點的時間,無法瞭解數據未達終點的狀態。因此有必要增強網絡層提供服務的服務質量。

2、引入傳輸層的原因

       面向連接的傳輸服務與面向連接的網絡服務類似,都分爲建立連接、數據傳輸、釋放連接三個階段;編址、尋址、流控制也是類似的。無連接的傳輸服務與無連接的網絡服務也非常類似。一個很顯然的問題:既然傳輸層的服務與網絡層的服務如此相似,那麼爲什麼我們還要兩個獨立的層呢?

      原因在於:傳輸層的代碼完全運行在用戶的機器上,但是網絡層主要運行在由承運商控制的路由器上。試想以下幾種情況?

①       網絡層提供的服務不夠用;

②       頻繁的丟失分組;

③       路由器時常崩潰。

       用戶在網絡層上並沒有真正的控制權,所以他們不可能用最好的路由器或者在數據鏈路層上用更好的錯誤處理機制來解決服務太差的問題。唯一的可能是在網絡層之上的另一層中提高服務質量。這就是傳輸層存在的必要性。

      傳輸層的重要性:不僅僅是另外一層,它是整個協議層次的核心所在。如果沒有傳輸層,那麼分層協議的整個概念將變得沒有意義。

      傳輸層的任務:在源機器和目標機器之間提供可靠的、性價比合理的數據傳輸服務,並且與當前使用的物理網絡完全獨立。

 

3、傳輸層的功能

        數據傳送,不關心數據含義,進程間通信。

        彌補高層(上3層)要求與網絡層(基於下3層)數據傳送服務質量間的差異(差錯率、差錯恢復能力、吞吐率、延時、費用等),對高層屏蔽網絡層的服務的差異,提供穩定和一致的界面。

4、傳輸層協議與網絡層協議的主要區別

       網絡層(IP層)提供點到點的連接即提供主機之間的邏輯通信,傳輸層提供端到端的連接——提供進程之間的邏輯通信。

5、傳輸層的用途

      傳輸層將數據分段,並進行必要的控制,以便將這些片段重組成各種通信流。在此過程中,傳輸層主要負責:

①       跟蹤源主機和目的主機上應用程序間的每次通信;

②       將數據分段,並管理每個片段;

③       將分段數據重組爲應用程序數據流;

④       標識不同的應用程序。

6、端口號的概念

        運行在計算機中的進程是用進程標識符來標誌的。運行在應用層的各種應用進程卻不應當讓計算機操作系統指派它的進程標識符。這是因爲在因特網上使用的計算機的操作系統種類很多,而不同的操作系統又使用不同格式的進程標識符。爲了使運行不同操作系統的計算機的應用進程能夠互相通信,就必須用統一的方法對TCP/IP體系的應用進程進行標誌。

解決這個問題的方法就是在運輸層使用協議端口號(protocol port number),或通常簡稱爲端口(port)。

雖然通信的終點是應用進程,但我們可以把端口想象是通信的終點,因爲我們只要把要傳送的報文交到目的主機的某一個合適的目的端口,剩下的工作(即最後交付目的進程)就由 TCP來完成。

  

 

7、傳輸層的主要協議

          TCP/ IP傳輸層的兩個主要協議都是因特網的重要標準,傳輸控制協議TCP(Transmission Control Protocol)[RFC 768]、用戶數據報協議UDP(User Datagram Protocol)[RFC 793]。

          傳輸層的數據流要在網絡端點之間建立邏輯連接。如果使用UDP,傳輸層的首要任務是將數據從源設備傳輸到目的設備。如果使用TCP,傳輸層主要通過滑動窗口來提供端到端控制,以及利用確認序列號和確認信息提供可靠性。傳輸層定義主機應用程序之間端到端的連接。

 

8、TCP&UDP的比較

       TCP(Transmission Control Protocol)可靠的、面向連接的協議(eg:打電話)、傳輸效率低全雙工通信(發送緩存&接收緩存)、面向字節流。使用TCP的應用:Web瀏覽器;電子郵件、文件傳輸程序。

       UDP(User Datagram Protocol)不可靠的、無連接的服務,傳輸效率高(發送前時延小),一對一、一對多、多對一、多對多、面向報文,盡最大努力服務,無擁塞控制。使用UDP的應用:域名系統 (DNS);視頻流;IP語音(VoIP)。

 問題1:什麼是面向連接、面向無連接?

        面向連接舉例:兩個人之間通過電話進行通信。

面向無連接舉例:郵政服務,用戶把信函放在郵件中期待郵政處理流程來傳遞郵政包裹。顯然,不可達代表不可靠。

         從程序實現的角度解析面向連接、面向無連接如下:

         TCP面向連接,UDP面向無連接(在默認的阻塞模式下):

         在TCP協議中,當客戶端退出程序或斷開連接時,TCP協議的recv函數會立即返回不再阻塞,因爲服務端自己知道客戶端已經退出或斷開連接,證明它是面向連接的;

        而在UDP協議中,recvfrom這個接收函數將會始終保持阻塞,因爲服務端自己不知道客戶端已經退出或斷開連接,證明它是面向無連接的)。

 

       從上圖也能清晰的看出,TCP通信需要服務器端偵聽listen、接收客戶端連接請求accept,等待客戶端connect建立連接後才能進行數據包的收發(recv/send)工作。

         而UDP則服務器和客戶端的概念不明顯,服務器端即接收端需要綁定端口,等待客戶端的數據的到來。後續便可以進行數據的收發(recvfrom/sendto)工作。

問題2:什麼是面向字節流、面向報文?

       面向字節流:雖然應用程序和TCP的交互是一次一個數據塊(大小不等),但TCP把應用程序看成是一連串的無結構的字節流。TCP有一個緩衝,當應用程序傳送的數據塊太長,TCP就可以把它劃分短一些再傳送。如果應用程序一次只發送一個字節,TCP也可以等待積累有足夠多的字節後再構成報文段發送出去。

       面向報文:面向報文的傳輸方式是應用層交給UDP多長的報文,UDP就照樣發送,即一次發送一個報文。因此,應用程序必須選擇合適大小的報文。若報文太長,則IP層需要分片,降低效率。若太短,會是IP太小。(謝希仁,第五版。UDP對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界。這也就是說,應用層交給UDP多長的報文,UDP就照樣發送),即一次發送一個報文)。

問題3:在默認的阻塞模式下,爲什麼說TCP無邊界,UDP有邊界?

         對於TCP協議,客戶端連續發送數據,只要服務端的這個函數的緩衝區足夠大,會一次性接收過來,即客戶端是分好幾次發過來,是有邊界的,而服務端卻一次性接收過來,所以證明是無邊界的;

        而對於UDP協議,客戶端連續發送數據,即使服務端的這個函數的緩衝區足夠大,也只會一次一次的接收,發送多少次接收多少次,即客戶端分幾次發送過來,服務端就必須按幾次接收,從而證明,這種UDP的通訊模式是有邊界的。

問題4:UDP 如何發送大量的數據?如何處理分包?

        用 updclient 一次不能發送太大的數據量,不然就會報錯:一個在數據報套接字上發送的消息大於內部消息緩衝器或其他一些網絡限制,或該用戶用於接收數據報的緩衝器比數據報小。但不知道一次到底能發多少字節?如果把一個大的字節數組拆分成若干個字節數組發送,那麼接收時如何判斷和處理呢?

       答:方法很簡單:

1、在客戶端將你要發送的內容(文件什麼的都可以)分塊,每塊內容進行編號,然後發送;

2、服務端在接收到你的分塊數據以後,根據你的客戶端數據內容的編號重新組裝;

3、一般我們在發送數據的時候,儘量採用比較小的數據塊的方式(我的都沒有超過1024的),數據塊太大的話容易出現發送和接收的數據時間長,匹配出問題。

問題5.UDP發包的問題

       問:udp發送兩次數據,第一次 100字節,第二次200字節,接包方一次recvfrom( 1000 ),收到是 100,還是200,還是300?

       答:UDP是數據報文協議,是以數據包方式,所以每次可以接收100,200,在理想情況下,第一次是無論recvfrom多少都是接收到100。當然,可能由於網絡原因,第二個包先到的話,有可能是200了。對可能會由於網絡原因亂序,所以可能先收到200,所以自定義的udp協議包頭裏都要加上一個序列號,標識發送與收包對應。

問題6.TCP的發包問題

       問:同樣如果換成tcp,第一次發送 100字節,第二次發送200字節,recv( 1000 )會接收到多少?

       答:tcp是流協議,所以recv( 1000 ),會收到300 tcp自己處理好了重傳,保證數據包的完整性

問題7.有分片的情況下如下處理

        問:如果MTU是1500,使用UDP發送 2000,那麼recvfrom(2000)是收到1500,還是2000?

        答:還是接收2000,數據分片由ip層處理了,放到udp還是一個完整的包。接收到的包是由路由路徑上最少的MTU來分片,注意轉到UDP已經在是組裝好的(組裝出錯的包會經crc校驗出錯而丟棄),是一個完整的數據包。

問題8.分片後的處理

       問:如果500那個片丟了怎麼辦?udp又沒有重傳

       答:udp裏有個crc檢驗,如果包不完整就會丟棄,也不會通知是否接收成功,所以UDP是不可靠的傳輸協議,而且TCP不存在這個問題,有自己的重傳機制。在內網來說,UDP基本不會有丟包,可靠性還是有保障。當然如果是要求有時序性和高可靠性,還是走TCP,不然就要自己提供重傳和亂序處理( UDP內網發包處理量可以達 7M~10M/s )

問題9.不同連接到同一個端口的包處理

       問:TCP

          A -> C發100

          B -> C發200

         AB同時同一端口

         C recv(1000) ,會收到多少?

      答:A與C是一個tcp連接,B與C又是另一個tcp連接,所以不同socket,所以分開處理。每個socket有自己的接收緩衝和發送緩衝

問題10.什麼是TCP粘包

        在應用開發過程中,基於TCP網絡傳輸的應用程序有時會出現粘包現象(即發送方發送的若干包數據到接收方接收時粘成一包)。詳細解釋如下:由於TCP是流協議,對於一個socket的包,如發送 10AAAAABBBBB兩次,由於網絡原因第一次又分成兩次發送, 10AAAAAB和BBBB,如果接包的時候先讀取10(包長度)再讀入後續數據,當接收得快,發送的慢時,就會出現先接收了 10AAAAAB,會解釋錯誤 ,再接到BBBB10AAAAABBBBB,也解釋錯誤的情況。這就是TCP的粘包。

       在網絡傳輸應用中,通常需要在網絡協議之上再自定義一個協議封裝一下,簡單做法就是在要發送的數據前面再加一個自定義的包頭,包頭中可以包含數據長度和其它一些信息,接收的時候先收包頭,再根據包頭中描述的數據長度來接收後面的數據。詳細做法是:先接收包頭,在包頭裏指定包體長度來接收。設置包頭包尾的檢查位(如羣空間0x2開頭,0x3結束來檢查一個包是否完整)。對於TCP來說:1)不存在丟包,錯包,所以不會出現數據出錯 2)如果包頭檢測錯誤,即爲非法或者請求,直接重置即可

       爲了避免粘包現象,可採取以下幾種措施。

        一是對於發送方引起的粘包現象,用戶可通過編程設置來避免,TCP提供了強制數據立即傳送的操作指令push,TCP軟件收到該操作指令後,就立即將本段數據發送出去,而不必等待發送緩衝區滿;

        二是對於接收方引起的粘包,則可通過優化程序設計、精簡接收進程工作量、提高接收進程優先級等措施,使其及時接收數據,從而儘量避免出現粘包現象;

         三是由接收方控制,將一包數據按結構字段,人爲控制分多次接收,然後合併,通過這種手段來避免粘包。

問題11.圖解TCP的3次握手建立連接,4次握手釋放連接?

         TCP是面向連接的協議。運輸連接是用來傳送TCP報文的。TCP傳輸連接的建立和釋放是每一次面向連接的通信中必不可少的過程。因此,傳輸連接就由三個階段,即:連接建立、數據傳送和連接釋放。

 

      這裏的SYN=SYNchronization,SYN=1,ACK=0,表示連接請求報文段;同意建立連接則SYN=1,ACK=1,連接後所有的ACK=1。

三次握手(three-way handshake)方案解決了由於網絡層會丟失、存儲和重複分組帶來的問題。試想不進行三次握手可能出現的問題?

 

      

        如上圖所示,如果僅僅是2次握手的話,可能出現的問題如下:

       Host A發送的數據包由於網絡的原因,出現了滯留,即延時到達了HostB。此時,B以爲HostA發來了請求,於是就向HostA發送確認報文,以建立連接。而HostA收到報文後,由於其沒有向HostB發起建立連接的請求,因此不會理睬HostB的確認,也不會向HostB發送數據。而此時的B認爲已經建立起連接了,就等待HostA發送的數據,導致HostB的資源白白浪費!

 

連接釋放:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章