[計網]TCP/UDP 多路復用/分用


一、解析

1.1 應用層、運輸層以及網絡層的關系

網絡層是五層結構中的第三層,它的作用就是提供端到端的(主機之間)的通信;而運輸層屬於第四層,它的作用是提供進程間的通信。應用層則是最頂層,作用是提供為用戶提供與網絡打交道的接口

應用層與運輸層之間通過套接字進行數據傳遞數據,套接字是運輸層與應用層的一個中間媒介,位於兩層之間。運輸層接收到數據后,將它交付到正確的套接字中,應用層進程從相應的套接字中獲取數據;反之應用層將數據交付到套接字,運輸層從套接字中收集數據。而網絡層接受其他主機發送的數據,去除首部信息后交給運輸層,由運輸層定向到套接字;反之運輸層也將從套接字中收集的數據封裝后,交給網絡層向下傳遞。

1.2 什么是多路復用與多路分解

通過類比來理解這兩個概念:假設兩個家庭A和B,各有10名家庭成員。假設這兩個家庭的每一個成員,在每個星期都要給另一個家庭的10名成員各寫一封信,所以A家庭每星期都有100封信送到B家庭,B家庭亦是如此。A家庭和B家庭各選出了一個負責人來處理這件事,假設A家庭的負責人是李明,而B家庭的負責人是韓梅梅,這兩個人每個星期需要干兩件事:

  1. 收集每個家庭成員寫的信,並將它交給郵差,由郵差將信交到另一個家庭中
  2. 郵差將信寄到家來時,負責人統一接收,並根據信上的收件人姓名,將信交給指定的家庭成員;

多路復用的過程就好比負責人要辦的事情1,而多路分解就好比事情2。下面兩個名次的解釋:

多路復用:在數據的發送端,傳輸層收集各個套接字中需要發送的數據,將它們封裝上首部信息(之后用於分解),交給網絡層

多路分解:在數據的接收端,傳輸層接收到網絡層的報文后,並將它交付到正確的套接字上

家庭成員就好比套接字,而這兩個負責人就好比主機中的運輸層,郵差可以理解為網絡層。負責人將寄來的信息發給家庭成員的過程,類似於運輸層將數據報分發給指定的套接字;而郵差從一個家庭到另一個家庭的過程也可以類比為網絡層主機之間的通信。

那這兩個過程具體如何工作呢?每個進程可以由多個套接字,運輸層如何知道要將數據交付給哪一個套接字呢?這里我們需要明確復用/分解的要求:

1.每個套接字都有唯一標識

2.每一個傳遞到運輸層的報文段,都包含一些特殊字段,來指明它交付到的套接字;

對於每一個套接字,都能被分配一個的端口號。所以,上述要求2中所說的特殊字段就是源端口號字段(對於TCP和UDP,這個還有一些其他特殊字段)。所以我們知道運輸層如何實現分解服務了:當一個報文段到達運輸層時,運輸層檢測報文段中的端口號,根據端口號,將其定向到指定的套接字中,然后數據將通過套接字即可進入套接字對應的進程。

1.3 無連接的多路復用和多路分解

上面只是講解了一下這兩個概念的一般形式,但是在具體的實現中要稍微復雜一些,不同協議所使用的套接字也有所區別,下面我們來看看UDP協議中的多路分解與多路復用。

  我們知道,UDP是一個面向無連接,不可靠的運輸層協議,它盡最大努力傳輸數據,但是不保證數據是否到達,或者是否按順序到達,它要做的僅僅是將數據發出,至於發出后如何,它不會在意。

  當進程需要發送UDP數據報時,首先要創建一個UDP套接字,然后應用層通過這個UDP套接字將數據傳遞到運輸層,運輸層為數據加上源端口號以及目的端口號,封裝成數據報后交給網絡層,網絡層再為數據報封裝上源IP以及目的IP。由於UDP協議僅僅只是將數據發出,所以對於UDP報文來說,最重要的就是目的地址的所在。可能正是因為這個原因,一個UDP套接字的標識就是目的IP+目的端口號。因此對於多個不同的UDP數據報,只要它們的目的IP+端口號相同,就算源地址不同,也會在目的主機中被定向到同一個UDP套接字中,被同一個進程所接收。目的IP決定了數據報將要發送到哪台主機,而目的端口號為運輸層的的分解提供了標識。

  這里可能就會有些疑問了,既然這樣,那UDP報文為什么需要包含源IP+源端口號呢(IP在網絡層被封裝)?這是因為UDP是無連接的,當接收到一個UDP報文時,可能想要回送一個報文,這時候不知道源在何處將無法實現。所以當需要向源主機回復報文時,只需提取UDP報文中的源IP和源端口號,然后將它們作為目的IP+目的端口號即可實現。

 

上面只是講解了一下這兩個概念的一般形式,但是在具體的實現中要稍微復雜一些,不同協議所使用的套接字也有所區別,下面我們來看看UDP協議中的多路分解與多路復用。

  我們知道,UDP是一個面向無連接,不可靠的運輸層協議,它盡最大努力傳輸數據,但是不保證數據是否到達,或者是否按順序到達,它要做的僅僅是將數據發出,至於發出后如何,它不會在意。

  當進程需要發送UDP數據報時,首先要創建一個UDP套接字,然后應用層通過這個UDP套接字將數據傳遞到運輸層,運輸層為數據加上源端口號以及目的端口號,封裝成數據報后交給網絡層,網絡層再為數據報封裝上源IP以及目的IP。由於UDP協議僅僅只是將數據發出,所以對於UDP報文來說,最重要的就是目的地址的所在。可能正是因為這個原因,一個UDP套接字的標識就是目的IP+目的端口號。因此對於多個不同的UDP數據報,只要它們的目的IP+端口號相同,就算源地址不同,也會在目的主機中被定向到同一個UDP套接字中,被同一個進程所接收。目的IP決定了數據報將要發送到哪台主機,而目的端口號為運輸層的的分解提供了標識。

  這里可能就會有些疑問了,既然這樣,那UDP報文為什么需要包含源IP+源端口號呢(IP在網絡層被封裝)?這是因為UDP是無連接的,當接收到一個UDP報文時,可能想要回送一個報文,這時候不知道源在何處將無法實現。所以當需要向源主機回復報文時,只需提取UDP報文中的源IP和源端口號,然后將它們作為目的IP+目的端口號即可實現。

 

 

1.4 面向連接的多路復用與多路分解

 

既然有無連接的實現,自然就有連接的實現。運輸層乃至整個計算機網絡最著名的協議——TCP協議,就是一個面向連接的協議。TCP是一個面向連接,可靠的運輸層協議。既然面向連接,那它就需要關注兩個方面:源地址目的地址,因為TCP的傳輸,需要兩邊協作完成。正因為TCP的特性,導致TCP的套接字和UDP也有所區別。TCP套接字的標識是一個四元組,即源IP+源端口+目的IP+目的端口UDP是目的IP+目的端口)。我們通過一個實例來講解TCP的多路復用/分解過程。

  大部分人使用最多的應用層協議應該就是HTTP協議,而它就是基於TCP協議實現的,當我們在瀏覽器中請求一個頁面時,將經歷以下過程:

  1. Web服務器監聽80端口,等待客戶端的連接;
  2. 用戶在瀏覽器輸入一個URL,回車后,瀏覽器進程創建一個套接字,此套接字由服務器IP,服務器80端口,本地IP,本地進程端口,四部分標識;
  3. 瀏覽器進程將數據通過此套接字從應用層傳入運輸層,運輸層為TCP報文加上首部(包括源端口和目的端口)后,交給網絡層,網絡層為其加上網絡層首部(包括源IP和目的IP)傳輸傳輸到Web服務器;
  4. Web服務器的接收到此數據報后,檢測到數據報請求的是端口80,於是檢測80端口正在運行,且允許連接,則創建一個新的套接字,此套接字由服務器IP,服務器80端口,源IP,源端口,這四部分標識;
  5. 此后到達的Web服務器的數據報,若以上四部分完全相等,則將進入此套接字中;

  既然TCP套接字是由源IP+源端口+目的IP+目的端口四部分標識,不難想到,我們無法在同一台主機上,依靠同一個端口,向服務器的某個一個端口建立兩個TCP連接,因為這樣將無法區分兩個連接。以下通過Java進行測試:

public static void main(String[] args) throws IOException { // 建立第一個TCP連接,結果正常 Socket socket1 = new Socket("www.baidu.com", 80, null, 8888); // 建立第二個連接,與上一個連接的目的IP,目的端口,以及本地端口均相同 // 結果拋出異常: // java.net.BindException: Address already in use: JVM_Bind Socket socket2 = new Socket("www.baidu.com", 80, null, 8888); } 

  以上代碼執行時拋出異常,提示地址已經被使用,但是修改第二個socket對象的本地端口后,異常消失,驗證了上面的結論。

 二、參考

計算機網絡——多路復用與多路分解 - 特務依昂 - 博客園 (cnblogs.com)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM