日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

快速理解网络通信协议

發(fā)布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 快速理解网络通信协议 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、正文引言


我們每天使用互聯(lián)網(wǎng),你是否想過,它是如何實現(xiàn)的?

全世界幾十億臺電腦,連接在一起,兩兩通信。上海的某一塊網(wǎng)卡送出信號,洛杉磯的另一塊網(wǎng)卡居然就收到了,兩者實際上根本不知道對方的物理位置,你不覺得這是很神奇的事情嗎?

互聯(lián)網(wǎng)的核心是一系列協(xié)議,總稱為"互聯(lián)網(wǎng)協(xié)議"(Internet Protocol Suite)。它們對電腦如何連接和組網(wǎng),做出了詳盡的規(guī)定。理解了這些協(xié)議,就理解了互聯(lián)網(wǎng)的原理。

下面就是我的學(xué)習(xí)筆記。因為這些協(xié)議實在太復(fù)雜、太龐大,我想整理一個簡潔的框架,幫助自己從總體上把握它們。為了保證簡單易懂,我做了大量的簡化,有些地方并不全面和精確,但是應(yīng)該能夠說清楚互聯(lián)網(wǎng)的原理。

2、內(nèi)容概述


2.1五層模型


互聯(lián)網(wǎng)的實現(xiàn),分成好幾層。每一層都有自己的功能,就像建筑物一樣,每一層都靠下一層支持。用戶接觸到的,只是最上面的一層,根本沒有感覺到下面的層。要理解互聯(lián)網(wǎng),必須從最下層開始,自下而上理解每一層的功能。

如何分層有不同的模型,有的模型分七層,有的分四層。我覺得,把互聯(lián)網(wǎng)分成五層,比較容易解釋:
?

如上圖所示,最底下的一層叫做"實體層"(Physical Layer),最上面的一層叫做"應(yīng)用層"(Application Layer),中間的三層(自下而上)分別是"鏈接層"(Link Layer)、"網(wǎng)絡(luò)層"(Network Layer)和"傳輸層"(Transport Layer)。越下面的層,越靠近硬件;越上面的層,越靠近用戶。

它們叫什么名字,其實并不重要。只需要知道,互聯(lián)網(wǎng)分成若干層就可以了。

2.2層與協(xié)議


每一層都是為了完成一種功能。為了實現(xiàn)這些功能,就需要大家都遵守共同的規(guī)則。大家都遵守的規(guī)則,就叫做"協(xié)議"(protocol)。

互聯(lián)網(wǎng)的每一層,都定義了很多協(xié)議。這些協(xié)議的總稱,就叫做"互聯(lián)網(wǎng)協(xié)議"(Internet Protocol Suite)。它們是互聯(lián)網(wǎng)的核心,下面介紹每一層的功能,主要就是介紹每一層的主要協(xié)議。

3、實體層


我們從最底下的一層開始。

電腦要組網(wǎng),第一件事要干什么?當(dāng)然是先把電腦連起來,可以用光纜、電纜、雙絞線、無線電波等方式。

?

這就叫做"實體層",它就是把電腦連接起來的物理手段。它主要規(guī)定了網(wǎng)絡(luò)的一些電氣特性,作用是負責(zé)傳送0和1的電信號。

4、鏈接層


4.1定義


單純的0和1沒有任何意義,必須規(guī)定解讀方式:多少個電信號算一組?每個信號位有何意義?

這就是"鏈接層"的功能,它在"實體層"的上方,確定了0和1的分組方式。

4.2以太網(wǎng)協(xié)議


早期的時候,每家公司都有自己的電信號分組方式。逐漸地,一種叫做"以太網(wǎng)"(Ethernet)的協(xié)議,占據(jù)了主導(dǎo)地位。

以太網(wǎng)規(guī)定,一組電信號構(gòu)成一個數(shù)據(jù)包,叫做"幀"(Frame)。每一幀分成兩個部分:標(biāo)頭(Head)和數(shù)據(jù)(Data)。

?

"標(biāo)頭"包含數(shù)據(jù)包的一些說明項,比如發(fā)送者、接受者、數(shù)據(jù)類型等等;"數(shù)據(jù)"則是數(shù)據(jù)包的具體內(nèi)容。

"標(biāo)頭"的長度,固定為18字節(jié)。"數(shù)據(jù)"的長度,最短為46字節(jié),最長為1500字節(jié)。因此,整個"幀"最短為64字節(jié),最長為1518字節(jié)。如果數(shù)據(jù)很長,就必須分割成多個幀進行發(fā)送。

4.3MAC地址


上面提到,以太網(wǎng)數(shù)據(jù)包的"標(biāo)頭",包含了發(fā)送者和接受者的信息。那么,發(fā)送者和接受者是如何標(biāo)識呢?

以太網(wǎng)規(guī)定,連入網(wǎng)絡(luò)的所有設(shè)備,都必須具有"網(wǎng)卡"接口。數(shù)據(jù)包必須是從一塊網(wǎng)卡,傳送到另一塊網(wǎng)卡。網(wǎng)卡的地址,就是數(shù)據(jù)包的發(fā)送地址和接收地址,這叫做MAC地址。

?

每塊網(wǎng)卡出廠的時候,都有一個全世界獨一無二的MAC地址,長度是48個二進制位,通常用12個十六進制數(shù)表示。

?

前6個十六進制數(shù)是廠商編號,后6個是該廠商的網(wǎng)卡流水號。有了MAC地址,就可以定位網(wǎng)卡和數(shù)據(jù)包的路徑了。

4.4廣播


定義地址只是第一步,后面還有更多的步驟:

  • 1)首先:一塊網(wǎng)卡怎么會知道另一塊網(wǎng)卡的MAC地址?
    回答是有一種ARP協(xié)議,可以解決這個問題。這個留到后面介紹,這里只需要知道,以太網(wǎng)數(shù)據(jù)包必須知道接收方的MAC地址,然后才能發(fā)送。

  • 2)其次:就算有了MAC地址,系統(tǒng)怎樣才能把數(shù)據(jù)包準(zhǔn)確送到接收方?
    回答是以太網(wǎng)采用了一種很"原始"的方式,它不是把數(shù)據(jù)包準(zhǔn)確送到接收方,而是向本網(wǎng)絡(luò)內(nèi)所有計算機發(fā)送,讓每臺計算機自己判斷,是否為接收方。


?

上圖中,1號計算機向2號計算機發(fā)送一個數(shù)據(jù)包,同一個子網(wǎng)絡(luò)的3號、4號、5號計算機都會收到這個包。它們讀取這個包的"標(biāo)頭",找到接收方的MAC地址,然后與自身的MAC地址相比較,如果兩者相同,就接受這個包,做進一步處理,否則就丟棄這個包。這種發(fā)送方式就叫做"廣播"(broadcasting)。

有了數(shù)據(jù)包的定義、網(wǎng)卡的MAC地址、廣播的發(fā)送方式,"鏈接層"就可以在多臺計算機之間傳送數(shù)據(jù)了。

5、網(wǎng)絡(luò)層


5.1網(wǎng)絡(luò)層的由來


以太網(wǎng)協(xié)議,依靠MAC地址發(fā)送數(shù)據(jù)。理論上,單單依靠MAC地址,上海的網(wǎng)卡就可以找到洛杉磯的網(wǎng)卡了,技術(shù)上是可以實現(xiàn)的。

但是,這樣做有一個重大的缺點。以太網(wǎng)采用廣播方式發(fā)送數(shù)據(jù)包,所有成員人手一"包",不僅效率低,而且局限在發(fā)送者所在的子網(wǎng)絡(luò)。也就是說,如果兩臺計算機不在同一個子網(wǎng)絡(luò),廣播是傳不過去的。這種設(shè)計是合理的,否則互聯(lián)網(wǎng)上每一臺計算機都會收到所有包,那會引起災(zāi)難。

互聯(lián)網(wǎng)是無數(shù)子網(wǎng)絡(luò)共同組成的一個巨型網(wǎng)絡(luò),很像想象上海和洛杉磯的電腦會在同一個子網(wǎng)絡(luò),這幾乎是不可能的。

?

因此,必須找到一種方法,能夠區(qū)分哪些MAC地址屬于同一個子網(wǎng)絡(luò),哪些不是。如果是同一個子網(wǎng)絡(luò),就采用廣播方式發(fā)送,否則就采用"路由"方式發(fā)送。("路由"的意思,就是指如何向不同的子網(wǎng)絡(luò)分發(fā)數(shù)據(jù)包,這是一個很大的主題,本文不涉及。)遺憾的是,MAC地址本身無法做到這一點。它只與廠商有關(guān),與所處網(wǎng)絡(luò)無關(guān)。

這就導(dǎo)致了"網(wǎng)絡(luò)層"的誕生。它的作用是引進一套新的地址,使得我們能夠區(qū)分不同的計算機是否屬于同一個子網(wǎng)絡(luò)。這套地址就叫做"網(wǎng)絡(luò)地址",簡稱"網(wǎng)址"。

于是,"網(wǎng)絡(luò)層"出現(xiàn)以后,每臺計算機有了兩種地址,一種是MAC地址,另一種是網(wǎng)絡(luò)地址。兩種地址之間沒有任何聯(lián)系,MAC地址是綁定在網(wǎng)卡上的,網(wǎng)絡(luò)地址則是管理員分配的,它們只是隨機組合在一起。

網(wǎng)絡(luò)地址幫助我們確定計算機所在的子網(wǎng)絡(luò),MAC地址則將數(shù)據(jù)包送到該子網(wǎng)絡(luò)中的目標(biāo)網(wǎng)卡。因此,從邏輯上可以推斷,必定是先處理網(wǎng)絡(luò)地址,然后再處理MAC地址。

5.2IP協(xié)議


規(guī)定網(wǎng)絡(luò)地址的協(xié)議,叫做IP協(xié)議。它所定義的地址,就被稱為IP地址。目前,廣泛采用的是IP協(xié)議第四版,簡稱IPv4。
IPv4這個版本規(guī)定,網(wǎng)絡(luò)地址由32個二進制位組成:
?

習(xí)慣上,我們用分成四段的十進制數(shù)表示IP地址,從0.0.0.0一直到255.255.255.255

互聯(lián)網(wǎng)上的每一臺計算機,都會分配到一個IP地址。這個地址分成兩個部分,前一部分代表網(wǎng)絡(luò),后一部分代表主機。比如,IP地址172.16.254.1,這是一個32位的地址,假定它的網(wǎng)絡(luò)部分是前24位(172.16.254),那么主機部分就是后8位(最后的那個1)。處于同一個子網(wǎng)絡(luò)的電腦,它們IP地址的網(wǎng)絡(luò)部分必定是相同的,也就是說172.16.254.2應(yīng)該與172.16.254.1處在同一個子網(wǎng)絡(luò)。

但是,問題在于單單從IP地址,我們無法判斷網(wǎng)絡(luò)部分。還是以172.16.254.1為例,它的網(wǎng)絡(luò)部分,到底是前24位,還是前16位,甚至前28位,從IP地址上是看不出來的。

那么,怎樣才能從IP地址,判斷兩臺計算機是否屬于同一個子網(wǎng)絡(luò)呢?這就要用到另一個參數(shù)"子網(wǎng)掩碼"(subnet mask)。

所謂"子網(wǎng)掩碼",就是表示子網(wǎng)絡(luò)特征的一個參數(shù)。它在形式上等同于IP地址,也是一個32位二進制數(shù)字,它的網(wǎng)絡(luò)部分全部為1,主機部分全部為0。比如,IP地址172.16.254.1,如果已知網(wǎng)絡(luò)部分是前24位,主機部分是后8位,那么子網(wǎng)絡(luò)掩碼就是11111111.11111111.11111111.00000000,寫成十進制就是255.255.255.0

知道"子網(wǎng)掩碼",我們就能判斷,任意兩個IP地址是否處在同一個子網(wǎng)絡(luò)。方法是將兩個IP地址與子網(wǎng)掩碼分別進行AND運算(兩個數(shù)位都為1,運算結(jié)果為1,否則為0),然后比較結(jié)果是否相同,如果是的話,就表明它們在同一個子網(wǎng)絡(luò)中,否則就不是。

比如,已知IP地址172.16.254.1和172.16.254.233的子網(wǎng)掩碼都是255.255.255.0,請問它們是否在同一個子網(wǎng)絡(luò)?兩者與子網(wǎng)掩碼分別進行AND運算,結(jié)果都是172.16.254.0,因此它們在同一個子網(wǎng)絡(luò)。

總結(jié)一下,IP協(xié)議的作用主要有兩個,一個是為每一臺計算機分配IP地址,另一個是確定哪些地址在同一個子網(wǎng)絡(luò)。

5.3IP數(shù)據(jù)包


根據(jù)IP協(xié)議發(fā)送的數(shù)據(jù),就叫做IP數(shù)據(jù)包。不難想象,其中必定包括IP地址信息。但是前面說過,以太網(wǎng)數(shù)據(jù)包只包含MAC地址,并沒有IP地址的欄位。那么是否需要修改數(shù)據(jù)定義,再添加一個欄位呢?

回答是不需要,我們可以把IP數(shù)據(jù)包直接放進以太網(wǎng)數(shù)據(jù)包的"數(shù)據(jù)"部分,因此完全不用修改以太網(wǎng)的規(guī)格。這就是互聯(lián)網(wǎng)分層結(jié)構(gòu)的好處:上層的變動完全不涉及下層的結(jié)構(gòu)。

具體來說,IP數(shù)據(jù)包也分為"標(biāo)頭"和"數(shù)據(jù)"兩個部分:
?

"標(biāo)頭"部分主要包括版本、長度、IP地址等信息,"數(shù)據(jù)"部分則是IP數(shù)據(jù)包的具體內(nèi)容。它放進以太網(wǎng)數(shù)據(jù)包后,以太網(wǎng)數(shù)據(jù)包就變成了下面這樣:
?

IP數(shù)據(jù)包的"標(biāo)頭"部分的長度為20到60字節(jié),整個數(shù)據(jù)包的總長度最大為65,535字節(jié)。因此,理論上,一個IP數(shù)據(jù)包的"數(shù)據(jù)"部分,最長為65,515字節(jié)。前面說過,以太網(wǎng)數(shù)據(jù)包的"數(shù)據(jù)"部分,最長只有1500字節(jié)。因此,如果IP數(shù)據(jù)包超過了1500字節(jié),它就需要分割成幾個以太網(wǎng)數(shù)據(jù)包,分開發(fā)送了。

5.4ARP協(xié)議


關(guān)于"網(wǎng)絡(luò)層",還有最后一點需要說明。因為IP數(shù)據(jù)包是放在以太網(wǎng)數(shù)據(jù)包里發(fā)送的,所以我們必須同時知道兩個地址,一個是對方的MAC地址,另一個是對方的IP地址。通常情況下,對方的IP地址是已知的(后文會解釋),但是我們不知道它的MAC地址。

所以,我們需要一種機制,能夠從IP地址得到MAC地址。

這里又可以分成兩種情況:

  • 1)第一種情況:如果兩臺主機不在同一個子網(wǎng)絡(luò),那么事實上沒有辦法得到對方的MAC地址,只能把數(shù)據(jù)包傳送到兩個子網(wǎng)絡(luò)連接處的"網(wǎng)關(guān)"(gateway),讓網(wǎng)關(guān)去處理;

  • 2)第二種情況:如果兩臺主機在同一個子網(wǎng)絡(luò),那么我們可以用ARP協(xié)議,得到對方的MAC地址。ARP協(xié)議也是發(fā)出一個數(shù)據(jù)包(包含在以太網(wǎng)數(shù)據(jù)包中),其中包含它所要查詢主機的IP地址,在對方的MAC地址這一欄,填的是FF:FF:FF:FF:FF:FF,表示這是一個"廣播"地址。它所在子網(wǎng)絡(luò)的每一臺主機,都會收到這個數(shù)據(jù)包,從中取出IP地址,與自身的IP地址進行比較。如果兩者相同,都做出回復(fù),向?qū)Ψ綀蟾孀约旱腗AC地址,否則就丟棄這個包。


總之,有了ARP協(xié)議之后,我們就可以得到同一個子網(wǎng)絡(luò)內(nèi)的主機MAC地址,可以把數(shù)據(jù)包發(fā)送到任意一臺主機之上了。

6、傳輸層


6.1傳輸層的由來


有了MAC地址和IP地址,我們已經(jīng)可以在互聯(lián)網(wǎng)上任意兩臺主機上建立通信。

接下來的問題是,同一臺主機上有許多程序都需要用到網(wǎng)絡(luò),比如,你一邊瀏覽網(wǎng)頁,一邊與朋友在線聊天。當(dāng)一個數(shù)據(jù)包從互聯(lián)網(wǎng)上發(fā)來的時候,你怎么知道,它是表示網(wǎng)頁的內(nèi)容,還是表示在線聊天的內(nèi)容?

也就是說,我們還需要一個參數(shù),表示這個數(shù)據(jù)包到底供哪個程序(進程)使用。這個參數(shù)就叫做"端口"(port),它其實是每一個使用網(wǎng)卡的程序的編號。每個數(shù)據(jù)包都發(fā)到主機的特定端口,所以不同的程序就能取到自己所需要的數(shù)據(jù)。

"端口"是0到65535之間的一個整數(shù),正好16個二進制位。0到1023的端口被系統(tǒng)占用,用戶只能選用大于1023的端口。不管是瀏覽網(wǎng)頁還是在線聊天,應(yīng)用程序會隨機選用一個端口,然后與服務(wù)器的相應(yīng)端口聯(lián)系。

"傳輸層"的功能,就是建立"端口到端口"的通信。相比之下,"網(wǎng)絡(luò)層"的功能是建立"主機到主機"的通信。只要確定主機和端口,我們就能實現(xiàn)程序之間的交流。因此,Unix系統(tǒng)就把主機+端口,叫做"套接字"(socket)。有了它,就可以進行網(wǎng)絡(luò)應(yīng)用程序開發(fā)了。

6.2UDP協(xié)議


現(xiàn)在,我們必須在數(shù)據(jù)包中加入端口信息,這就需要新的協(xié)議。最簡單的實現(xiàn)叫做UDP協(xié)議,它的格式幾乎就是在數(shù)據(jù)前面,加上端口號。

UDP數(shù)據(jù)包,也是由"標(biāo)頭"和"數(shù)據(jù)"兩部分組成:
?


"標(biāo)頭"部分主要定義了發(fā)出端口和接收端口,"數(shù)據(jù)"部分就是具體的內(nèi)容。然后,把整個UDP數(shù)據(jù)包放入IP數(shù)據(jù)包的"數(shù)據(jù)"部分,而前面說過,IP數(shù)據(jù)包又是放在以太網(wǎng)數(shù)據(jù)包之中的,所以整個以太網(wǎng)數(shù)據(jù)包現(xiàn)在變成了下面這樣:
?

UDP數(shù)據(jù)包非常簡單,"標(biāo)頭"部分一共只有8個字節(jié),總長度不超過65,535字節(jié),正好放進一個IP數(shù)據(jù)包。

6.3TCP協(xié)議


UDP協(xié)議的優(yōu)點是比較簡單,容易實現(xiàn),但是缺點是可靠性較差,一旦數(shù)據(jù)包發(fā)出,無法知道對方是否收到。為了解決這個問題,提高網(wǎng)絡(luò)可靠性,TCP協(xié)議就誕生了。這個協(xié)議非常復(fù)雜,但可以近似認為,它就是有確認機制的UDP協(xié)議,每發(fā)出一個數(shù)據(jù)包都要求確認。如果有一個數(shù)據(jù)包遺失,就收不到確認,發(fā)出方就知道有必要重發(fā)這個數(shù)據(jù)包了。

因此,TCP協(xié)議能夠確保數(shù)據(jù)不會遺失。它的缺點是過程復(fù)雜、實現(xiàn)困難、消耗較多的資源。

TCP數(shù)據(jù)包和UDP數(shù)據(jù)包一樣,都是內(nèi)嵌在IP數(shù)據(jù)包的"數(shù)據(jù)"部分。TCP數(shù)據(jù)包沒有長度限制,理論上可以無限長,但是為了保證網(wǎng)絡(luò)的效率,通常TCP數(shù)據(jù)包的長度不會超過IP數(shù)據(jù)包的長度,以確保單個TCP數(shù)據(jù)包不必再分割。

7、應(yīng)用層


應(yīng)用程序收到"傳輸層"的數(shù)據(jù),接下來就要進行解讀。由于互聯(lián)網(wǎng)是開放架構(gòu),數(shù)據(jù)來源五花八門,必須事先規(guī)定好格式,否則根本無法解讀。"應(yīng)用層"的作用,就是規(guī)定應(yīng)用程序的數(shù)據(jù)格式。

舉例來說,TCP協(xié)議可以為各種各樣的程序傳遞數(shù)據(jù),比如Email、WWW、FTP等等。那么,必須有不同協(xié)議規(guī)定電子郵件、網(wǎng)頁、FTP數(shù)據(jù)的格式,這些應(yīng)用程序協(xié)議就構(gòu)成了"應(yīng)用層"。這是最高的一層,直接面對用戶。它的數(shù)據(jù)就放在TCP數(shù)據(jù)包的"數(shù)據(jù)"部分。

因此,現(xiàn)在的以太網(wǎng)的數(shù)據(jù)包就變成下面這樣:
?

8、一個小結(jié)

我們已經(jīng)知道,網(wǎng)絡(luò)通信就是交換數(shù)據(jù)包。電腦A向電腦B發(fā)送一個數(shù)據(jù)包,后者收到了,回復(fù)一個數(shù)據(jù)包,從而實現(xiàn)兩臺電腦之間的通信。

數(shù)據(jù)包的結(jié)構(gòu),基本上是下面這樣:
?

發(fā)送這個包,需要知道兩個地址:

  • * 對方的MAC地址;

  • * 對方的IP地址。


有了這兩個地址,數(shù)據(jù)包才能準(zhǔn)確送到接收者手中。但是,前面說過,MAC地址有局限性,如果兩臺電腦不在同一個子網(wǎng)絡(luò),就無法知道對方的MAC地址,必須通過網(wǎng)關(guān)(gateway)轉(zhuǎn)發(fā)。

?

上圖中,1號電腦要向4號電腦發(fā)送一個數(shù)據(jù)包。它先判斷4號電腦是否在同一個子網(wǎng)絡(luò),結(jié)果發(fā)現(xiàn)不是(后文介紹判斷方法),于是就把這個數(shù)據(jù)包發(fā)到網(wǎng)關(guān)A。網(wǎng)關(guān)A通過路由協(xié)議,發(fā)現(xiàn)4號電腦位于子網(wǎng)絡(luò)B,又把數(shù)據(jù)包發(fā)給網(wǎng)關(guān)B,網(wǎng)關(guān)B再轉(zhuǎn)發(fā)到4號電腦。

1號電腦把數(shù)據(jù)包發(fā)到網(wǎng)關(guān)A,必須知道網(wǎng)關(guān)A的MAC地址。所以,數(shù)據(jù)包的目標(biāo)地址,實際上分成兩種情況:

場景數(shù)據(jù)包地址
同一個子網(wǎng)絡(luò)對方的MAC地址,對方的IP地址
非同一個子網(wǎng)絡(luò)網(wǎng)關(guān)的MAC地址,對方的IP地址


發(fā)送數(shù)據(jù)包之前,電腦必須判斷對方是否在同一個子網(wǎng)絡(luò),然后選擇相應(yīng)的MAC地址。接下來,我們就來看,實際使用中,這個過程是怎么完成的。

9、用戶的上網(wǎng)設(shè)置


9.1靜態(tài)IP地址


你買了一臺新電腦,插上網(wǎng)線,開機,這時電腦能夠上網(wǎng)嗎?

?

通常你必須做一些設(shè)置。有時,管理員(或者ISP)會告訴你下面四個參數(shù),你把它們填入操作系統(tǒng),計算機就能連上網(wǎng)了:

  • * 本機的IP地址;

  • * 子網(wǎng)掩碼;

  • * 網(wǎng)關(guān)的IP地址;

  • * DNS的IP地址。


下圖是Windows系統(tǒng)的設(shè)置窗口:
?

這四個參數(shù)缺一不可,后文會解釋為什么需要知道它們才能上網(wǎng)。由于它們是給定的,計算機每次開機,都會分到同樣的IP地址,所以這種情況被稱作"靜態(tài)IP地址上網(wǎng)"。但是,這樣的設(shè)置很專業(yè),普通用戶望而生畏,而且如果一臺電腦的IP地址保持不變,其他電腦就不能使用這個地址,不夠靈活。出于這兩個原因,大多數(shù)用戶使用"動態(tài)IP地址上網(wǎng)"。

9.2動態(tài)IP地址


所謂"動態(tài)IP地址",指計算機開機后,會自動分配到一個IP地址,不用人為設(shè)定。它使用的協(xié)議叫做DHCP協(xié)議。

這個協(xié)議規(guī)定,每一個子網(wǎng)絡(luò)中,有一臺計算機負責(zé)管理本網(wǎng)絡(luò)的所有IP地址,它叫做"DHCP服務(wù)器"。新的計算機加入網(wǎng)絡(luò),必須向"DHCP服務(wù)器"發(fā)送一個"DHCP請求"數(shù)據(jù)包,申請IP地址和相關(guān)的網(wǎng)絡(luò)參數(shù)。

前面說過,如果兩臺計算機在同一個子網(wǎng)絡(luò),必須知道對方的MAC地址和IP地址,才能發(fā)送數(shù)據(jù)包。但是,新加入的計算機不知道這兩個地址,怎么發(fā)送數(shù)據(jù)包呢?DHCP協(xié)議做了一些巧妙的規(guī)定。

9.3DHCP協(xié)議


首先,它是一種應(yīng)用層協(xié)議,建立在UDP協(xié)議之上,所以整個數(shù)據(jù)包是這樣的:
?

  • 1)最前面的"以太網(wǎng)標(biāo)頭":設(shè)置發(fā)出方(本機)的MAC地址和接收方(DHCP服務(wù)器)的MAC地址。前者就是本機網(wǎng)卡的MAC地址,后者這時不知道,就填入一個廣播地址:FF-FF-FF-FF-FF-FF。

  • 2)后面的"IP標(biāo)頭":設(shè)置發(fā)出方的IP地址和接收方的IP地址。這時,對于這兩者,本機都不知道。于是,發(fā)出方的IP地址就設(shè)為0.0.0.0,接收方的IP地址設(shè)為255.255.255.255。

  • 3)最后的"UDP標(biāo)頭":設(shè)置發(fā)出方的端口和接收方的端口。這一部分是DHCP協(xié)議規(guī)定好的,發(fā)出方是68端口,接收方是67端口。


這個數(shù)據(jù)包構(gòu)造完成后,就可以發(fā)出了。以太網(wǎng)是廣播發(fā)送,同一個子網(wǎng)絡(luò)的每臺計算機都收到了這個包。因為接收方的MAC地址是FF-FF-FF-FF-FF-FF,看不出是發(fā)給誰的,所以每臺收到這個包的計算機,還必須分析這個包的IP地址,才能確定是不是發(fā)給自己的。當(dāng)看到發(fā)出方IP地址是0.0.0.0,接收方是255.255.255.255,于是DHCP服務(wù)器知道"這個包是發(fā)給我的",而其他計算機就可以丟棄這個包。

接下來,DHCP服務(wù)器讀出這個包的數(shù)據(jù)內(nèi)容,分配好IP地址,發(fā)送回去一個"DHCP響應(yīng)"數(shù)據(jù)包。這個響應(yīng)包的結(jié)構(gòu)也是類似的,以太網(wǎng)標(biāo)頭的MAC地址是雙方的網(wǎng)卡地址,IP標(biāo)頭的IP地址是DHCP服務(wù)器的IP地址(發(fā)出方)和255.255.255.255(接收方),UDP標(biāo)頭的端口是67(發(fā)出方)和68(接收方),分配給請求端的IP地址和本網(wǎng)絡(luò)的具體參數(shù)則包含在Data部分。

新加入的計算機收到這個響應(yīng)包,于是就知道了自己的IP地址、子網(wǎng)掩碼、網(wǎng)關(guān)地址、DNS服務(wù)器等等參數(shù)。

9.4上網(wǎng)設(shè)置:小結(jié)


這個部分,需要記住的就是一點:不管是"靜態(tài)IP地址"還是"動態(tài)IP地址",電腦上網(wǎng)的首要步驟,是確定四個參數(shù)。

這四個值很重要,值得重復(fù)一遍:

  • * 本機的IP地址;

  • * 子網(wǎng)掩碼;

  • * 網(wǎng)關(guān)的IP地址;

  • * DNS的IP地址。


有了這幾個數(shù)值,電腦就可以上網(wǎng)"沖浪"了。接下來,我們來看一個實例,當(dāng)用戶訪問網(wǎng)頁的時候,互聯(lián)網(wǎng)協(xié)議是怎么運作的。

10、一個實例:訪問網(wǎng)頁


10.1本機參數(shù)


我們假定,經(jīng)過上一節(jié)的步驟,用戶設(shè)置好了自己的網(wǎng)絡(luò)參數(shù):

  • * 本機的IP地址:192.168.1.100;

  • * 子網(wǎng)掩碼:255.255.255.0;

  • * 網(wǎng)關(guān)的IP地址:192.168.1.1;

  • * DNS的IP地址:8.8.8.8。


然后他打開瀏覽器,想要訪問Google,在地址欄輸入了網(wǎng)址:www.google.com

?

這意味著,瀏覽器要向Google發(fā)送一個網(wǎng)頁請求的數(shù)據(jù)包。

10.2DNS協(xié)議


我們知道,發(fā)送數(shù)據(jù)包,必須要知道對方的IP地址。但是,現(xiàn)在,我們只知道網(wǎng)址www.google.com,不知道它的IP地址。DNS協(xié)議可以幫助我們,將這個網(wǎng)址轉(zhuǎn)換成IP地址。已知DNS服務(wù)器為8.8.8.8,于是我們向這個地址發(fā)送一個DNS數(shù)據(jù)包(53端口)。

?

然后,DNS服務(wù)器做出響應(yīng),告訴我們Google的IP地址是172.194.72.105。于是,我們知道了對方的IP地址。

10.3子網(wǎng)掩碼


接下來,我們要判斷,這個IP地址是不是在同一個子網(wǎng)絡(luò),這就要用到子網(wǎng)掩碼。

已知子網(wǎng)掩碼是255.255.255.0,本機用它對自己的IP地址192.168.1.100,做一個二進制的AND運算(兩個數(shù)位都為1,結(jié)果為1,否則為0),計算結(jié)果為192.168.1.0;然后對Google的IP地址172.194.72.105也做一個AND運算,計算結(jié)果為172.194.72.0。這兩個結(jié)果不相等,所以結(jié)論是,Google與本機不在同一個子網(wǎng)絡(luò)。

因此,我們要向Google發(fā)送數(shù)據(jù)包,必須通過網(wǎng)關(guān)192.168.1.1轉(zhuǎn)發(fā),也就是說,接收方的MAC地址將是網(wǎng)關(guān)的MAC地址。

10.4應(yīng)用層協(xié)議


瀏覽網(wǎng)頁用的是HTTP協(xié)議,它的整個數(shù)據(jù)包構(gòu)造是這樣的:
?

HTTP部分的內(nèi)容,類似于下面這樣:

123456789GET / HTTP/1.1Host: [url=http://www.google.com]www.google.com[/url]Connection: keep-aliveUser-Agent: Mozilla/5.0 (Windows NT 6.1) ......Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3Cookie: ... ...


我們假定這個部分的長度為4960字節(jié),它會被嵌在TCP數(shù)據(jù)包之中。

10.5TCP協(xié)議


TCP數(shù)據(jù)包需要設(shè)置端口,接收方(Google)的HTTP端口默認是80,發(fā)送方(本機)的端口是一個隨機生成的1024-65535之間的整數(shù),假定為51775。TCP數(shù)據(jù)包的標(biāo)頭長度為20字節(jié),加上嵌入HTTP的數(shù)據(jù)包,總長度變?yōu)?980字節(jié)。

10.6IP協(xié)議


然后,TCP數(shù)據(jù)包再嵌入IP數(shù)據(jù)包。IP數(shù)據(jù)包需要設(shè)置雙方的IP地址,這是已知的,發(fā)送方是192.168.1.100(本機),接收方是172.194.72.105(Google)。IP數(shù)據(jù)包的標(biāo)頭長度為20字節(jié),加上嵌入的TCP數(shù)據(jù)包,總長度變?yōu)?000字節(jié)。

10.7以太網(wǎng)協(xié)議


最后,IP數(shù)據(jù)包嵌入以太網(wǎng)數(shù)據(jù)包。以太網(wǎng)數(shù)據(jù)包需要設(shè)置雙方的MAC地址,發(fā)送方為本機的網(wǎng)卡MAC地址,接收方為網(wǎng)關(guān)192.168.1.1的MAC地址(通過ARP協(xié)議得到)。

以太網(wǎng)數(shù)據(jù)包的數(shù)據(jù)部分,最大長度為1500字節(jié),而現(xiàn)在的IP數(shù)據(jù)包長度為5000字節(jié)。因此,IP數(shù)據(jù)包必須分割成四個包。因為每個包都有自己的IP標(biāo)頭(20字節(jié)),所以四個包的IP數(shù)據(jù)包的長度分別為1500、1500、1500、560。

?

10.8服務(wù)器端響應(yīng)


經(jīng)過多個網(wǎng)關(guān)的轉(zhuǎn)發(fā),Google的服務(wù)器172.194.72.105,收到了這四個以太網(wǎng)數(shù)據(jù)包。根據(jù)IP標(biāo)頭的序號,Google將四個包拼起來,取出完整的TCP數(shù)據(jù)包,然后讀出里面的"HTTP請求",接著做出"HTTP響應(yīng)",再用TCP協(xié)議發(fā)回來。

本機收到HTTP響應(yīng)以后,就可以將網(wǎng)頁顯示出來,完成一次網(wǎng)絡(luò)通信。

?

這個例子就到此為止,雖然經(jīng)過了簡化,但它大致上反映了互聯(lián)網(wǎng)協(xié)議的整個通信過程。

11、TCP 協(xié)議的作用


互聯(lián)網(wǎng)由一整套協(xié)議構(gòu)成。TCP 只是其中的一層,有著自己的分工。

?
▲ TCP 是以太網(wǎng)協(xié)議和 IP 協(xié)議的上層協(xié)議,也是應(yīng)用層協(xié)議的下層協(xié)議

最底層的以太網(wǎng)協(xié)議(Ethernet)規(guī)定了電子信號如何組成數(shù)據(jù)包(packet),解決了子網(wǎng)內(nèi)部的點對點通信。

?
▲ 以太網(wǎng)協(xié)議解決了局域網(wǎng)的點對點通信

但是,以太網(wǎng)協(xié)議不能解決多個局域網(wǎng)如何互通,這由 IP 協(xié)議解決。

?
▲ IP 協(xié)議可以連接多個局域網(wǎng)

IP 協(xié)議定義了一套自己的地址規(guī)則,稱為 IP 地址。它實現(xiàn)了路由功能,允許某個局域網(wǎng)的 A 主機,向另一個局域網(wǎng)的 B 主機發(fā)送消息。

?
▲ 路由器就是基于 IP 協(xié)議。局域網(wǎng)之間要靠路由器連接

路由的原理很簡單。市場上所有的路由器,背后都有很多網(wǎng)口,要接入多根網(wǎng)線。路由器內(nèi)部有一張路由表,規(guī)定了 A 段 IP 地址走出口一,B 段地址走出口二,......通過這套"指路牌",實現(xiàn)了數(shù)據(jù)包的轉(zhuǎn)發(fā)。

?
▲ 本機的路由表注明了不同 IP 目的地的數(shù)據(jù)包,要發(fā)送到哪一個網(wǎng)口(interface)

IP 協(xié)議只是一個地址協(xié)議,并不保證數(shù)據(jù)包的完整。如果路由器丟包(比如緩存滿了,新進來的數(shù)據(jù)包就會丟失),就需要發(fā)現(xiàn)丟了哪一個包,以及如何重新發(fā)送這個包。這就要依靠 TCP 協(xié)議。
簡單說,TCP 協(xié)議的作用是,保證數(shù)據(jù)通信的完整性和可靠性,防止丟包。

12、TCP 數(shù)據(jù)包的大小


以太網(wǎng)數(shù)據(jù)包(packet)的大小是固定的,最初是1518字節(jié),后來增加到1522字節(jié)。其中, 1500 字節(jié)是負載(payload),22字節(jié)是頭信息(head)。IP 數(shù)據(jù)包在以太網(wǎng)數(shù)據(jù)包的負載里面,它也有自己的頭信息,最少需要20字節(jié),所以 IP 數(shù)據(jù)包的負載最多為1480字節(jié)。

?
▲ IP 數(shù)據(jù)包在以太網(wǎng)數(shù)據(jù)包里面,TCP 數(shù)據(jù)包在 IP 數(shù)據(jù)包里面

TCP 數(shù)據(jù)包在 IP 數(shù)據(jù)包的負載里面。它的頭信息最少也需要20字節(jié),因此 TCP 數(shù)據(jù)包的最大負載是 1480 - 20 = 1460 字節(jié)。由于 IP 和 TCP 協(xié)議往往有額外的頭信息,所以 TCP 負載實際為1400字節(jié)左右。因此,一條1500字節(jié)的信息需要兩個 TCP 數(shù)據(jù)包。HTTP/2 協(xié)議的一大改進, 就是壓縮 HTTP 協(xié)議的頭信息,使得一個 HTTP 請求可以放在一個 TCP 數(shù)據(jù)包里面,而不是分成多個,這樣就提高了速度

▲ 以太網(wǎng)數(shù)據(jù)包的負載是1500字節(jié),TCP 數(shù)據(jù)包的負載在1400字節(jié)左右

13、TCP 數(shù)據(jù)包的編號(SEQ)


一個包1400字節(jié),那么一次性發(fā)送大量數(shù)據(jù),就必須分成多個包。比如,一個 10MB 的文件,需要發(fā)送7100多個包。發(fā)送的時候,TCP 協(xié)議為每個包編號(sequence number,簡稱 SEQ),以便接收的一方按照順序還原。萬一發(fā)生丟包,也可以知道丟失的是哪一個包。

第一個包的編號是一個隨機數(shù)。為了便于理解,這里就把它稱為1號包。假定這個包的負載長度是100字節(jié),那么可以推算出下一個包的編號應(yīng)該是101。這就是說,每個數(shù)據(jù)包都可以得到兩個編號:自身的編號,以及下一個包的編號。接收方由此知道,應(yīng)該按照什么順序?qū)⑺鼈冞€原成原始文件。

▲ 當(dāng)前包的編號是45943,下一個數(shù)據(jù)包的編號是46183,由此可知,這個包的負載是240字節(jié)

14、TCP 數(shù)據(jù)包的組裝


收到 TCP 數(shù)據(jù)包以后,組裝還原是操作系統(tǒng)完成的。應(yīng)用程序不會直接處理 TCP 數(shù)據(jù)包。對于應(yīng)用程序來說,不用關(guān)心數(shù)據(jù)通信的細節(jié)。除非線路異常,收到的總是完整的數(shù)據(jù)。應(yīng)用程序需要的數(shù)據(jù)放在 TCP 數(shù)據(jù)包里面,有自己的格式(比如 HTTP 協(xié)議)。

TCP 并沒有提供任何機制,表示原始文件的大小,這由應(yīng)用層的協(xié)議來規(guī)定。比如,HTTP 協(xié)議就有一個頭信息Content-Length,表示信息體的大小。對于操作系統(tǒng)來說,就是持續(xù)地接收 TCP 數(shù)據(jù)包,將它們按照順序組裝好,一個包都不少。

操作系統(tǒng)不會去處理 TCP 數(shù)據(jù)包里面的數(shù)據(jù)。一旦組裝好 TCP 數(shù)據(jù)包,就把它們轉(zhuǎn)交給應(yīng)用程序。TCP 數(shù)據(jù)包里面有一個端口(port)參數(shù),就是用來指定轉(zhuǎn)交給監(jiān)聽該端口的應(yīng)用程序。



?

系統(tǒng)根據(jù) TCP 數(shù)據(jù)包里面的端口,將組裝好的數(shù)據(jù)轉(zhuǎn)交給相應(yīng)的應(yīng)用程序。上圖中,21端口是 FTP 服務(wù)器,25端口是 SMTP 服務(wù),80端口是 Web 服務(wù)器。

應(yīng)用程序收到組裝好的原始數(shù)據(jù),以瀏覽器為例,就會根據(jù) HTTP 協(xié)議的?Content-Length?字段正確讀出一段段的數(shù)據(jù)。這也意味著,一次 TCP 通信可以包括多個 HTTP 通信。

15、慢啟動和 ACK


服務(wù)器發(fā)送數(shù)據(jù)包,當(dāng)然越快越好,最好一次性全發(fā)出去。但是,發(fā)得太快,就有可能丟包。帶寬小、路由器過熱、緩存溢出等許多因素都會導(dǎo)致丟包。線路不好的話,發(fā)得越快,丟得越多。

最理想的狀態(tài)是,在線路允許的情況下,達到最高速率。但是我們怎么知道,對方線路的理想速率是多少呢?答案就是慢慢試。

TCP 協(xié)議為了做到效率與可靠性的統(tǒng)一,設(shè)計了一個慢啟動(slow start)機制。開始的時候,發(fā)送得較慢,然后根據(jù)丟包的情況,調(diào)整速率:如果不丟包,就加快發(fā)送速度;如果丟包,就降低發(fā)送速度。

Linux 內(nèi)核里面設(shè)定了(常量TCP_INIT_CWND),剛開始通信的時候,發(fā)送方一次性發(fā)送10個數(shù)據(jù)包,即"發(fā)送窗口"的大小為10。然后停下來,等待接收方的確認,再繼續(xù)發(fā)送。默認情況下,接收方每收到兩個 TCP 數(shù)據(jù)包,就要發(fā)送一個確認消息。"確認"的英語是 acknowledgement,所以這個確認消息就簡稱 ACK。

ACK 攜帶兩個信息:

  • 1)期待要收到下一個數(shù)據(jù)包的編號;

  • 2)接收方的接收窗口的剩余容量。


發(fā)送方有了這兩個信息,再加上自己已經(jīng)發(fā)出的數(shù)據(jù)包的最新編號,就會推測出接收方大概的接收速度,從而降低或增加發(fā)送速率。這被稱為"發(fā)送窗口",這個窗口的大小是可變的。

▲ 每個 ACK 都帶有下一個數(shù)據(jù)包的編號,以及接收窗口的剩余容量,雙方都會發(fā)送 ACK

注意:由于 TCP 通信是雙向的,所以雙方都需要發(fā)送 ACK。兩方的窗口大小,很可能是不一樣的。而且 ACK 只是很簡單的幾個字段,通常與數(shù)據(jù)合并在一個數(shù)據(jù)包里面發(fā)送。

上圖一共4次通信。第一次通信,A 主機發(fā)給B 主機的數(shù)據(jù)包編號是1,長度是100字節(jié),因此第二次通信 B 主機的 ACK 編號是 1 + 100 = 101,第三次通信 A 主機的數(shù)據(jù)包編號也是 101。同理,第二次通信 B 主機發(fā)給 A 主機的數(shù)據(jù)包編號是1,長度是200字節(jié),因此第三次通信 A 主機的 ACK 是201,第四次通信 B 主機的數(shù)據(jù)包編號也是201。

即使對于帶寬很大、線路很好的連接,TCP 也總是從10個數(shù)據(jù)包開始慢慢試,過了一段時間以后,才達到最高的傳輸速率。這就是 TCP 的慢啟動。

16、數(shù)據(jù)包的遺失處理


TCP 協(xié)議可以保證數(shù)據(jù)通信的完整性,這是怎么做到的?

前面說過,每一個數(shù)據(jù)包都帶有下一個數(shù)據(jù)包的編號。如果下一個數(shù)據(jù)包沒有收到,那么 ACK 的編號就不會發(fā)生變化。

舉例來說,現(xiàn)在收到了4號包,但是沒有收到5號包。ACK 就會記錄,期待收到5號包。過了一段時間,5號包收到了,那么下一輪 ACK 會更新編號。如果5號包還是沒收到,但是收到了6號包或7號包,那么 ACK 里面的編號不會變化,總是顯示5號包。這會導(dǎo)致大量重復(fù)內(nèi)容的 ACK。

如果發(fā)送方發(fā)現(xiàn)收到三個連續(xù)的重復(fù) ACK,或者超時了還沒有收到任何 ACK,就會確認丟包,即5號包遺失了,從而再次發(fā)送這個包。通過這種機制,TCP 保證了不會有數(shù)據(jù)包丟失。

▲ Host B 沒有收到100號數(shù)據(jù)包,會連續(xù)發(fā)出相同的 ACK,觸發(fā) Host A 重發(fā)100號數(shù)據(jù)包

17、建立連接方式的差異


17.1TCP


說到 TCP 建立連接,相信大多數(shù)人腦海里肯定可以浮現(xiàn)出一個詞,沒錯就是--“三次握手”。TCP 通過“三次握手”來建立連接,再通過“四次揮手”斷開一個連接。在每次揮手中 TCP 做了哪些操作呢?

流程如下圖所示(TCP的三次握手和四次揮手):

上圖就從客戶端和服務(wù)端的角度,清楚的展示了 TCP 的三次握手和四次揮手。可以看到,當(dāng) TCP 試圖建立連接時,三次握手指的是客戶端主動觸發(fā)了兩次,服務(wù)端觸發(fā)了一次。

我們可以先明確一下 TCP 建立連接并且初始化的目標(biāo)是什么呢?

  • 1)初始化資源;

  • 2)告訴對方我的序列號。


所以三次握手的次序是這樣子的:

  • 1)client端首先發(fā)送一個SYN包告訴Server端我的初始序列號是X;

  • 2)Server端收到SYN包后回復(fù)給client一個ACK確認包,告訴client說我收到了;

  • 3)接著Server端也需要告訴client端自己的初始序列號,于是Server也發(fā)送一個SYN包告訴client我的初始序列號是Y;

  • 4)Client收到后,回復(fù)Server一個ACK確認包說我知道了。


其中的 2 、3 步驟可以簡化為一步,也就是說將 ACK 確認包和 SYN 序列化包一同發(fā)送給 Client 端。到此我們就比較簡單的解釋了 TCP 建立連接的“三次握手”。

17.2UDP


我們都知道 TCP 是面向連接的、可靠的、有序的傳輸層協(xié)議,而 UDP 是面向數(shù)據(jù)報的、不可靠的、無序的傳輸協(xié)議,所以 UDP 壓根不會建立什么連接。

就好比發(fā)短信一樣,UDP 只需要知道對方的 ip 地址,將數(shù)據(jù)報一份一份的發(fā)送過去就可以了,其他的作為發(fā)送方,都不需要關(guān)心。

18、數(shù)據(jù)發(fā)送方式的差異


關(guān)于 TCP、UDP 之間數(shù)據(jù)發(fā)送的差異,可以體現(xiàn)二者最大的不同之處:

  • TCP:
    由于 TCP 是建立在兩端連接之上的協(xié)議,所以理論上發(fā)送的數(shù)據(jù)流不存在大小的限制。但是由于緩沖區(qū)有大小限制,所以你如果用 TCP 發(fā)送一段很大的數(shù)據(jù),可能會截斷成好幾段,接收方依次的接收。

  • UDP:
    由于 UDP 本身發(fā)送的就是一份一份的數(shù)據(jù)報,所以自然而然的就有一個上限的大小。


那么每次 UDP 發(fā)送的數(shù)據(jù)報大小由哪些因素共同決定呢?

  • UDP協(xié)議本身,UDP協(xié)議中有16位的UDP報文長度,那么UDP報文長度不能超過2^16=65536;

  • 以太網(wǎng)(Ethernet)數(shù)據(jù)幀的長度,數(shù)據(jù)鏈路層的MTU(最大傳輸單元);

  • socket的UDP發(fā)送緩存區(qū)大小。


先來看第一個因素,UDP 本身協(xié)議的報文長度為 2^16 - 1,UDP 包頭占 8 個字節(jié),IP 協(xié)議本身封裝后包頭占 20 個字節(jié),所以最終長度為: 2^16 - 1 - 20 - 8 = 65507 字節(jié)。

只看第一個因素有點理想化了,因為 UDP 屬于不可靠協(xié)議,我們應(yīng)該盡量避免在傳輸過程中,數(shù)據(jù)包被分割。所以這里有一個非常重要的概念 MTU -- 也就是最大傳輸單元。

在 Internet 下 MTU 的值為 576 字節(jié),所以在 internet 下使用 UDP 協(xié)議,每個數(shù)據(jù)報最大的字節(jié)數(shù)為: 576 - 20 - 8 = 548

19、數(shù)據(jù)有序性的差異


我們再來談?wù)剶?shù)據(jù)的有序性。

19.1TCP


對于 TCP 來說,本身 TCP 有著超時重傳、錯誤重傳、還有等等一系列復(fù)雜的算法保證了 TCP 的數(shù)據(jù)是有序的,假設(shè)你發(fā)送了數(shù)據(jù) 1、2、3,則只要發(fā)送端和接收端保持連接時,接收端收到的數(shù)據(jù)始終都是 1、2、3。

19.2UDP


而 UDP 協(xié)議則要奔放的多,無論 server 端無論緩沖池的大小有多大,接收 client 端發(fā)來的消息總是一個一個的接收。并且由于 UDP 本身的不可靠性以及無序性,如果 client 發(fā)送了 1、2、3 這三個數(shù)據(jù)報過來,server 端接收到的可能是任意順序、任意個數(shù)三個數(shù)據(jù)報的排列組合。

20、可靠性的差異


其實大家都知道 TCP 本身是可靠的協(xié)議,而 UDP 是不可靠的協(xié)議。

20.1TCP


TCP 內(nèi)部的很多算法機制讓他保持連接的過程中是很可靠的。比如:TCP 的超時重傳、錯誤重傳、TCP 的流量控制、阻塞控制、慢熱啟動算法、擁塞避免算法、快速恢復(fù)算法 等等。所以 TCP 是一個內(nèi)部原理復(fù)雜,但是使用起來比較簡單的這么一個協(xié)議。

20.2UDP


UDP 是一個面向非連接的協(xié)議,UDP 發(fā)送的每個數(shù)據(jù)報帶有自己的 IP 地址和接收方的 IP 地址,它本身對這個數(shù)據(jù)報是否出錯,是否到達不關(guān)心,只要發(fā)出去了就好了。

所以來研究下,什么情況會導(dǎo)致 UDP 丟包:

  • 數(shù)據(jù)報分片重組丟失:在文章之前我們就說過,UDP 的每個數(shù)據(jù)報大小多少最合適,事實上 UDP 協(xié)議本身規(guī)定的大小是 64kb,但是在數(shù)據(jù)鏈路層有 MTU 的限制,大小大概在 5kb,所以當(dāng)你發(fā)送一個很大的 UDP 包的時候,這個包會在 IP 層進行分片,然后重組。這個過程就有可能導(dǎo)致分片的包丟失。UDP 本身有 CRC 檢測機制,會拋棄掉丟失的 UDP 包;

  • UDP 緩沖區(qū)填滿:當(dāng) UDP 的緩沖區(qū)已經(jīng)被填滿的時候,接收方還沒有處理這部分的 UDP 數(shù)據(jù)報,這個時候再過來的數(shù)據(jù)報就沒有地方可以存了,自然就都被丟棄了。


21、使用場景總結(jié)


聊聊 TCP、UDP 使用場景。

先來說 UDP 的吧,有很多人都會覺得 UDP 與 TCP 相比,在性能速度上是占優(yōu)勢的。因為 UDP 并不用保持一個持續(xù)的連接,也不需要對收發(fā)包進行確認。但事實上經(jīng)過這么多年的發(fā)展 TCP 已經(jīng)擁有足夠多的算法和優(yōu)化,在網(wǎng)絡(luò)狀態(tài)不錯的情況下,TCP 的整體性能是優(yōu)于 UDP 的。

那在什么時候我們非用 UDP 不可呢?

  • 對實時性要求高:比如實時會議,實時視頻這種情況下,如果使用 TCP,當(dāng)網(wǎng)絡(luò)不好發(fā)生重傳時,畫面肯定會有延時,甚至越堆越多。如果使用 UDP 的話,即使偶爾丟了幾個包,但是也不會影響什么,這種情況下使用 UDP 比較好;

  • 多點通信:TCP 需要保持一個長連接,那么在涉及多點通訊的時候,肯定需要和多個通信節(jié)點建立其雙向連接,然后有時在NAT環(huán)境下,兩個通信節(jié)點建立其直接的 TCP 連接不是一個容易的事情,而 UDP 可以無需保持連接,直接發(fā)就可以了,所以成本會很低,而且穿透性好。這種情況下使用 UDP 也是沒錯的。


以上我們說了 UDP 的使用場景,在此之外的其他情況,使用 TCP 準(zhǔn)沒錯。

22、網(wǎng)速的提升給UDP穩(wěn)定性提供可靠網(wǎng)絡(luò)保障


CDN服務(wù)商Akamai報告從2008年到2015年7年時間,各個國家網(wǎng)絡(luò)平均速率由1.5Mbps提升為5.1Mbps,網(wǎng)速提升近4倍。網(wǎng)絡(luò)環(huán)境變好,網(wǎng)絡(luò)傳輸?shù)难舆t、穩(wěn)定性也隨之改善,UDP的丟包率低于5%,如果再使用應(yīng)用層重傳,能夠完全確保傳輸?shù)目煽啃浴?/span>

23、對比測試結(jié)果UDP性能優(yōu)于TCP


為了提升瀏覽速度,Google基于TCP提出了SPDY協(xié)議以及HTTP/2。Google在Chrome上實驗基于UDP的QUIC協(xié)議,傳輸速率減少到100ms以內(nèi)。

  • Google采用QUIC后連接速率能有效提升75%;

  • Google搜索采用QUIC后頁面加載性能提升3%;

  • YouTube采用QUIC后重新緩沖次數(shù)減少了30%。


24、TCP設(shè)計過于冗余,速度難以進一步提升


TCP為了實現(xiàn)網(wǎng)絡(luò)通信的可靠性,使用了復(fù)雜的擁塞控制算法,建立了繁瑣的握手過程以及重傳策略。由于TCP內(nèi)置在系統(tǒng)協(xié)議棧中,極難對其進行改進。?

25、UDP協(xié)議以其簡單、傳輸快的優(yōu)勢,在越來越多場景下取代了TCP


25.1網(wǎng)頁瀏覽


使用UDP協(xié)議有三個優(yōu)點 :

  • 能夠?qū)ξ帐诌^程進行精簡,減少網(wǎng)絡(luò)通信往返次數(shù);

  • 能夠?qū)LS加解密過程進行優(yōu)化;

  • 收發(fā)快速,無阻塞。


25.2流媒體


采用TCP,一旦發(fā)生丟包,TCP會將后續(xù)包緩存起來,等前面的包重傳并接收到后再繼續(xù)發(fā)送,延遲會越來越大。基于UDP的協(xié)議如實時音視頻開源工程WebRTC是極佳的選擇。

2010年google 通過收購 Global IP Solutions,獲得了WebRTC(網(wǎng)頁實時通信Web Real-Time Communication)技術(shù),用于提升網(wǎng)頁視頻速率。

25.3實時游戲


對實時要求較為嚴格的情況下,采用自定義的可靠UDP協(xié)議,比如Enet、RakNet(用戶有 sony online game、minecraft)等,自定義重傳策略,能夠把丟包產(chǎn)生的延遲降到最低,盡量減少網(wǎng)絡(luò)問題對游戲性造成的影響。

采用UDP的經(jīng)典游戲如FPS游戲Quake、CS,著名的游戲引擎Unity3D采用的也是RakNet。

25.4物聯(lián)網(wǎng)


2014年google旗下的Nest建立Thread Group,推出了物聯(lián)網(wǎng)通信協(xié)議Thread,完善物聯(lián)網(wǎng)通信。

采用UDP有3個關(guān)鍵點:

  • 網(wǎng)絡(luò)帶寬需求較小,而實時性要求高;

  • 大部分應(yīng)用無需維持連接;

  • 需要低功耗。


26、本文小結(jié)


如今全球?qū)⒔?0%的人都在使用互聯(lián)網(wǎng),人們不斷的追求更快、更好的服務(wù),一切都在變化,在越來越多的領(lǐng)域,UDP將會搶占TCP的主導(dǎo)地位。


總結(jié)

以上是生活随笔為你收集整理的快速理解网络通信协议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。