作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉(zhuǎn)載,也請保留這段聲明。謝謝!
我們已經(jīng)講解了物理層、連接層和網(wǎng)絡(luò)層。最開始的連接層協(xié)議種類繁多(Ethernet、Wifi、ARP等等)。到了網(wǎng)絡(luò)層,我們只剩下一個IP協(xié)議(IPv4和IPv6是替代關(guān)系)。進入到傳輸層(transport layer),協(xié)議的種類又開始繁多起來(比如TCP、UDP、SCTP等)。這就好像下面的大樹,根部(連接層)分叉很多,然后統(tǒng)一到一個樹干(網(wǎng)絡(luò)層),到了樹冠(傳輸層)部分又開始開始分叉,而每個樹枝上長出更多的樹葉(應(yīng)用層)。我們在網(wǎng)絡(luò)層已經(jīng)看到,通過樹干的統(tǒng)一,我們實現(xiàn)了一個覆蓋全球的互聯(lián)網(wǎng)絡(luò)(Internet)。然而,我們可能出于不同的目的利用這張“網(wǎng)”,隨之使用的方式也有所區(qū)分。不同的傳輸層協(xié)議(以及更多的應(yīng)用層協(xié)議)正是我們使用“網(wǎng)”的不同方式的體現(xiàn)。
網(wǎng)絡(luò)分層的“藝術(shù)”觀點
傳輸層最重要的協(xié)議為TCP協(xié)議和UDP協(xié)議。這兩者使用“網(wǎng)”的方式走了兩個極端。兩個協(xié)議的對比非常有趣。TCP協(xié)議復(fù)雜,但傳輸可靠。UDP協(xié)議簡單,但傳輸不可靠。其他的各個傳輸層協(xié)議在某種程度上都是這兩個協(xié)議的折中。我們先來看傳輸層協(xié)議中比較簡單的UDP協(xié)議。我們將參考許多之前文章的內(nèi)容(協(xié)議森林01, 03, 05)。
UDP(User Datagram Protocol)傳輸與IP傳輸非常類似。你可以將UDP協(xié)議看作IP協(xié)議暴露在傳輸層的一個接口。UDP協(xié)議同樣以數(shù)據(jù)包(datagram)的方式傳輸,它的傳輸方式也是的,所以UDP協(xié)議也是不可靠的(unreliable)。那么,我們?yōu)槭裁床恢苯邮褂肐P協(xié)議而要額外增加一個UDP協(xié)議呢? 一個重要的原因是IP協(xié)議中并沒有端口(port)的概念。IP協(xié)議進行的是IP地址到IP地址的傳輸,這意味者兩臺計算機之間的對話。但每臺計算機中需要有多個通信通道,并將多個通信通道分配給不同的進程使用(關(guān)于進程,可以參考Linux進程基礎(chǔ))。一個端口就代表了這樣的一個通信通道。正如我們在郵局和郵差中提到的收信人的概念一樣。UDP協(xié)議實現(xiàn)了端口,從而讓數(shù)據(jù)包可以在送到IP地址的基礎(chǔ)上,進一步可以送到某個端口。
UDP:依然不是那么“可靠”
盡管UDP協(xié)議非常簡單,但它的產(chǎn)生晚于更加復(fù)雜的TCP協(xié)議。早期的網(wǎng)絡(luò)開發(fā)者開發(fā)出IP協(xié)議和TCP協(xié)議分別位于網(wǎng)絡(luò)層和傳輸層,所有的通信都要先經(jīng)過TCP封裝,再經(jīng)過IP封裝(應(yīng)用層->TCP->IP)。開發(fā)者將TCP/IP視為相互合作的套裝。但很快,網(wǎng)絡(luò)開發(fā)者發(fā)現(xiàn),IP協(xié)議的功能和TCP協(xié)議的功能是相互獨立的。對于一些簡單的通信,我們只需要“Best Effort”式的IP傳輸就可以了,而不需要TCP協(xié)議復(fù)雜的建立連接的方式(特別是在早期網(wǎng)絡(luò)環(huán)境中,如果過多的建立TCP連接,會造成很大的網(wǎng)絡(luò)負(fù)擔(dān),而UDP協(xié)議可以相對快速的處理這些簡單通信)。UDP協(xié)議隨之被開發(fā)出來,作為IP協(xié)議在傳輸層的'傀儡'。這樣,網(wǎng)絡(luò)通信可以通過應(yīng)用層->UDP->IP的封裝方式,繞過TCP協(xié)議。由于UDP協(xié)議本身異常簡單,實際上只為IP傳輸起到了橋梁的作用。我們將在TCP協(xié)議的講解中看到更多TCP協(xié)議和UDP協(xié)議的對比。
IP和他的傀儡UDP
UDP的數(shù)據(jù)包同樣分為頭部(header)和數(shù)據(jù)(payload)兩部分。UDP是傳輸層(transport layer)協(xié)議,這意味著UDP的數(shù)據(jù)包需要經(jīng)過IP協(xié)議的封裝(encapsulation),然后通過IP協(xié)議傳輸到目的電腦。隨后UDP包在目的電腦拆封,并將信息送到相應(yīng)端口的緩存中。
來自wikipedia
上面的source port和destination port分別為UDP包的出發(fā)端口和目的地端口。Length為整個UDP包的長度。
checksum的算法與IP協(xié)議的header checksum算法相類似。然而,UDP的checksum所校驗的序列包括了整個UDP數(shù)據(jù)包,以及封裝的IP頭部的一些信息(主要為出發(fā)地IP和目的地IP)。這樣,checksum就可以校驗IP:端口的正確性了。在IPv4中,checksum可以為0,意味著不使用checksum。IPv6要求必須進行checksum校驗。
端口(port)是伴隨著傳輸層誕生的概念。它可以將網(wǎng)絡(luò)層的IP通信分送到各個通信通道。UDP協(xié)議和TCP協(xié)議盡管在工作方式上有很大的不同,但它們都建立了從一個端口到另一個端口的通信。
IP:端口
隨著我們進入傳輸層,我們也可以調(diào)用操作系統(tǒng)中的API,來構(gòu)建socket。Socket是操作系統(tǒng)提供的一個編程接口,它用來代表某個網(wǎng)絡(luò)通信。應(yīng)用程序通過socket來調(diào)用系統(tǒng)內(nèi)核中處理網(wǎng)絡(luò)協(xié)議的模塊,而這些內(nèi)核模塊會負(fù)責(zé)具體的網(wǎng)絡(luò)協(xié)議的實施。這樣,我們可以讓內(nèi)核來接收網(wǎng)絡(luò)協(xié)議的細(xì)節(jié),而我們只需要提供所要傳輸?shù)膬?nèi)容就可以了,內(nèi)核會幫我們控制格式,并進一步向底層封裝。因此,在實際應(yīng)用中,我們并不需要知道具體怎么構(gòu)成一個UDP包,而只需要提供相關(guān)信息(比如IP地址,比如端口號,比如所要傳輸?shù)男畔?,操作系統(tǒng)內(nèi)核會在傳輸之前會根據(jù)我們提供的相關(guān)信息構(gòu)成一個合格的UDP包(以及下層的包和幀)。socket是一個比較大的課題,在協(xié)議森林系列中不會過多深入。
(在原始Python服務(wù)器我們討論了如何使用socket建立一個TCP連接,可以作為一個參考)
端口是傳輸層帶來的最重要的概念。我們進一步了解了UDP協(xié)議。如果已經(jīng)掌握了IP協(xié)議,那么UDP協(xié)議就沒有任何困難可言,它只是IP協(xié)議暴露在傳輸層上的接口。
歡迎繼續(xù)閱讀“協(xié)議森林”系列
聯(lián)系客服