我們已經講解了物理層、連線層和網路層。最開始的連線層協議種類繁多(ethernet、wifi、arp等等)。到了網路層,我們只剩下乙個ip協議(ipv4和ipv6是替代關係)。進入到傳輸層(transport layer),協議的種類又開始繁多起來(比如tcp、udp、sctp等)。這就好像下面的大樹,根部(連線層)分叉很多,然後統一到乙個樹幹(網路層),到了樹冠(傳輸層)部分又開始開始分叉,而每個樹枝上長出更多的樹葉(應用層)。我們在網路層已經看到,通過樹幹的統一,我們實現了乙個覆蓋全球的網際網路絡(internet)。然而,我們可能出於不同的目的利用這張「網」,隨之使用的方式也有所區分。不同的傳輸層協議(以及更多的應用層協議)正是我們使用「網」的不同方式的體現。
網路分層的「藝術」觀點
傳輸層最重要的協議為tcp協議和udp協議。這兩者使用「網」的方式走了兩個極端。兩個協議的對比非常有趣。tcp協議複雜,但傳輸可靠。udp協議簡單,但傳輸不可靠。其他的各個傳輸層協議在某種程度上都是這兩個協議的折中。我們先來看傳輸層協議中比較簡單的udp協議。我們將參考許多之前文章的內容(協議森林01, 03, 05)。
udp(user datagram protocol)傳輸與ip傳輸非常類似。你可以將udp協議看作ip協議暴露在傳輸層的乙個介面。udp協議同樣以資料報(datagram)的方式傳輸,它的傳輸方式也是"best
effort"的,所以udp協議也是不可靠的(unreliable)。那麼,我們為什麼不直接使用ip協議而要額外增加乙個udp協議呢? 乙個重要的原因是ip協議中並沒有埠(port)的概念。ip協議進行的是ip位址到ip位址的傳輸,這意味者兩台計算機之間的對話。但每台計算機中需要有多個通訊通道,並將多個通訊通道分配給不同的程序使用(關於程序,可以參考linux程序基礎)。乙個埠就代表了這樣的乙個通訊通道。正如我們在郵局和郵差中提到的收信人的概念一樣。udp協議實現了埠,從而讓資料報可以在送到ip位址的基礎上,進一步可以送到某個埠。
udp:依然不是那麼「可靠」
儘管udp協議非常簡單,但它的產生晚於更加複雜的tcp協議。早期的網路開發者開發出ip協議和tcp協議分別位於網路層和傳輸層,所有的通訊都要先經過tcp封裝,再經過ip封裝(應用層->tcp->ip)。開發者將tcp/ip視為相互合作的套裝。但很快,網路開發者發現,ip協議的功能和tcp協議的功能是相互獨立的。對於一些簡單的通訊,我們只需要「best
effort」式的ip傳輸就可以了,而不需要tcp協議複雜的建立連線的方式(特別是在早期網路環境中,如果過多的建立tcp連線,會造成很大的網路負擔,而udp協議可以相對快速的處理這些簡單通訊)。udp協議隨之被開發出來,作為ip協議在傳輸層的"傀儡"。這樣,網路通訊可以通過應用層->udp->ip的封裝方式,繞過tcp協議。由於udp協議本身異常簡單,實際上只為ip傳輸起到了橋梁的作用。我們將在tcp協議的講解中看到更多tcp協議和udp協議的對比。
ip和他的傀儡udp
udp的資料報同樣分為頭部(header)和資料(payload)兩部分。udp是傳輸層(transport layer)協議,這意味著udp的資料報需要經過ip協議的封裝(encapsulation),然後通過ip協議傳輸到目的電腦。隨後udp包在目的電腦拆封,並將資訊送到相應埠的快取中。
來自wikipedia
上面的source port和destination port分別為udp包的出發埠和目的地埠。length為整個udp包的長度。
checksum的演算法與ip協議的header
checksum演算法相類似。然而,udp的checksum所校驗的序列包括了整個udp資料報,以及封裝的ip頭部的一些資訊(主要為出發地ip和目的地ip)。這樣,checksum就可以校驗ip:埠的正確性了。在ipv4中,checksum可以為0,意味著不使用checksum。ipv6要求必須進行checksum校驗。
埠(port)是伴隨著傳輸層誕生的概念。它可以將網路層的ip通訊分送到各個通訊通道。udp協議和tcp協議儘管在工作方式上有很大的不同,但它們都建立了從乙個埠到另乙個埠的通訊。
ip:埠
隨著我們進入傳輸層,我們也可以呼叫作業系統中的api,來構建socket。socket是作業系統提供的乙個程式設計介面,它用來代表某個網路通訊。應用程式通過socket來呼叫系統核心中處理網路協議的模組,而這些核心模組會負責具體的網路協議的實施。這樣,我們可以讓核心來接收網路協議的細節,而我們只需要提供所要傳輸的內容就可以了,核心會幫我們控制格式,並進一步向底層封裝。因此,在實際應用中,我們並不需要知道具體怎麼構成乙個udp包,而只需要提供相關資訊(比如ip位址,比如埠號,比如所要傳輸的資訊),作業系統核心會在傳輸之前會根據我們提供的相關資訊構成乙個合格的udp包(以及下層的包和幀)。socket是乙個比較大的課題,在協議森林系列中不會過多深入。
(在原始python伺服器我們討論了如何使用socket建立乙個tcp連線,可以作為乙個參考)
埠是傳輸層帶來的最重要的概念。我們進一步了解了udp協議。如果已經掌握了ip協議,那麼udp協議就沒有任何困難可言,它只是ip協議暴露在傳輸層上的介面。
udp套介面是無連線的、不可靠的資料報協議;既然他不可靠為什麼還要用呢?其一:當應用程式使用廣播或多播時只能使用udp協議;其二:由於他是無連線的,所以速度快。因為udp套介面是無連線的,如果一方的資料報丟失,那另一方將無限等待,解決辦法是設定乙個超時。
建立udp套介面時socket函式的第二個引數應該是sock_dgram,說明是建立乙個udp套介面;由於udp是無連線的,所以伺服器端並不需要listen或accept函式。
使用udp套接字程式設計可以實現基於tcp/ip協議的面向無連線的通訊,它分為伺服器端和客戶端兩部分,其主要實現過程如圖3.1所示。
圖3.1 udp客戶/伺服器的套接字函式
UDP協議總結
1 tcp ip詳解 卷1 協議 2 tcp ip協議族 第4版 3 計算機網路 第5版 使用者資料報協議的英文縮寫為udp,udp是一種無連線且不可靠的運輸層協議,udp沒有流量控制和擁塞控制,除了檢驗和之外,沒有其他的差錯控制。i.udp資料報 udp資料報由udp首部和資料組成,其中udp首部...
可靠UDP傳輸協議總結
tcp ip協議棧中,tcp和udp屬於傳輸層,負責實現資料的傳輸。其中tcp是面向連線的和基於單個位元組流的 保證順序的可靠傳輸協議,udp是無連線的 不可靠的 面向報文的協議。在實際應用中,tcp由於簡單可靠,被大部分應用層協議使用,特別是http,所以佔據了網際網路流量的主要部分。由於tcp的...
可靠UDP傳輸協議總結
tcp ip協議棧中,tcp和udp屬於傳輸層,負責實現資料的傳輸。其中tcp是面向連線的和基於單個位元組流的 保證順序的可靠傳輸協議,udp是無連線的 不可靠的 面向報文的協議。在實際應用中,tcp由於簡單可靠,被大部分應用層協議使用,特別是http,所以佔據了網際網路流量的主要部分。由於tcp的...