互聯(lián)網(wǎng)協(xié)議入門
來源:阮一峰地網(wǎng)絡(luò)日志
作者:阮一峰
注:帥地玩編程做了些小修改
我們已經(jīng)知道,網(wǎng)絡(luò)通信就是交換數(shù)據(jù)包。電腦A向電腦B發(fā)送一個(gè)數(shù)據(jù)包,后者收到了,回復(fù)一個(gè)數(shù)據(jù)包,從而實(shí)現(xiàn)兩臺(tái)電腦之間的通信。數(shù)據(jù)包的結(jié)構(gòu),基本上是下面這樣:

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

上圖中,1號(hào)電腦要向4號(hào)電腦發(fā)送一個(gè)數(shù)據(jù)包。它先判斷4號(hào)電腦是否在同一個(gè)子網(wǎng)絡(luò),結(jié)果發(fā)現(xiàn)不是(后文介紹判斷方法),于是就把這個(gè)數(shù)據(jù)包發(fā)到網(wǎng)關(guān)A。網(wǎng)關(guān)A通過路由協(xié)議,發(fā)現(xiàn)4號(hào)電腦位于子網(wǎng)絡(luò)B,又把數(shù)據(jù)包發(fā)給網(wǎng)關(guān)B,網(wǎng)關(guān)B再轉(zhuǎn)發(fā)到4號(hào)電腦。
1號(hào)電腦把數(shù)據(jù)包發(fā)到網(wǎng)關(guān)A,必須知道網(wǎng)關(guān)A的MAC地址。所以,數(shù)據(jù)包的目標(biāo)地址,實(shí)際上分成兩種情況:

發(fā)送數(shù)據(jù)包之前,電腦必須判斷對(duì)方是否在同一個(gè)子網(wǎng)絡(luò),然后選擇相應(yīng)的MAC地址。接下來,我們就來看,實(shí)際使用中,這個(gè)過程是怎么完成的。
2、用戶的上網(wǎng)設(shè)置
靜態(tài)IP地址
你買了一臺(tái)新電腦,插上網(wǎng)線,開機(jī),這時(shí)電腦能夠上網(wǎng)嗎?

通常你必須做一些設(shè)置。有時(shí),管理員(或者ISP)會(huì)告訴你下面四個(gè)參數(shù),你把它們填入操作系統(tǒng),計(jì)算機(jī)就能連上網(wǎng)了:
(1) 本機(jī)的IP地址
(2) 網(wǎng)掩碼
(3) 網(wǎng)關(guān)的IP地址
(4) DNS的IP地址
下圖是Windows系統(tǒng)的設(shè)置窗口。

這四個(gè)參數(shù)缺一不可,后文會(huì)解釋為什么需要知道它們才能上網(wǎng)。由于它們是給定的,計(jì)算機(jī)每次開機(jī),都會(huì)分到同樣的IP地址,所以這種情況被稱作"靜態(tài)IP地址上網(wǎng)"。
但是,這樣的設(shè)置很專業(yè),普通用戶望而生畏,而且如果一臺(tái)電腦的IP地址保持不變,其他電腦就不能使用這個(gè)地址,不夠靈活。出于這兩個(gè)原因,大多數(shù)用戶使用"動(dòng)態(tài)IP地址上網(wǎng)"。
動(dòng)態(tài)IP地址
所謂"動(dòng)態(tài)IP地址",指計(jì)算機(jī)開機(jī)后,會(huì)自動(dòng)分配到一個(gè)IP地址,不用人為設(shè)定。它使用的協(xié)議叫做DHCP協(xié)議。
這個(gè)協(xié)議規(guī)定,每一個(gè)子網(wǎng)絡(luò)中,有一臺(tái)計(jì)算機(jī)負(fù)責(zé)管理本網(wǎng)絡(luò)的所有IP地址,它叫做"DHCP服務(wù)器"。新的計(jì)算機(jī)加入網(wǎng)絡(luò),必須向"DHCP服務(wù)器"發(fā)送一個(gè)"DHCP請(qǐng)求"數(shù)據(jù)包,申請(qǐng)IP地址和相關(guān)的網(wǎng)絡(luò)參數(shù)。
前面說過,如果兩臺(tái)計(jì)算機(jī)在同一個(gè)子網(wǎng)絡(luò),必須知道對(duì)方的MAC地址和IP地址,才能發(fā)送數(shù)據(jù)包。但是,新加入的計(jì)算機(jī)不知道這兩個(gè)地址,怎么發(fā)送數(shù)據(jù)包呢?
DHCP協(xié)議做了一些巧妙的規(guī)定。
DHCP協(xié)議
首先,它是一種應(yīng)用層協(xié)議,建立在UDP協(xié)議之上,所以整個(gè)數(shù)據(jù)包是這樣的:

(1)最前面的"以太網(wǎng)標(biāo)頭",設(shè)置發(fā)出方(本機(jī))的MAC地址和接收方(DHCP服務(wù)器)的MAC地址。前者就是本機(jī)網(wǎng)卡的MAC地址,后者這時(shí)不知道,就填入一個(gè)廣播地址:FF-FF-FF-FF-FF-FF。
(2)后面的"IP標(biāo)頭",設(shè)置發(fā)出方的IP地址和接收方的IP地址。這時(shí),對(duì)于這兩者,本機(jī)都不知道。于是,發(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端口。
這個(gè)數(shù)據(jù)包構(gòu)造完成后,就可以發(fā)出了。以太網(wǎng)是廣播發(fā)送,同一個(gè)子網(wǎng)絡(luò)的每臺(tái)計(jì)算機(jī)都收到了這個(gè)包。因?yàn)榻邮辗降腗AC地址是FF-FF-FF-FF-FF-FF,看不出是發(fā)給誰的,所以每臺(tái)收到這個(gè)包的計(jì)算機(jī),還必須分析這個(gè)包的IP地址,才能確定是不是發(fā)給自己的。當(dāng)看到發(fā)出方IP地址是0.0.0.0,接收方是255.255.255.255,于是DHCP服務(wù)器知道"這個(gè)包是發(fā)給我的",而其他計(jì)算機(jī)就可以丟棄這個(gè)包。
接下來,DHCP服務(wù)器讀出這個(gè)包的數(shù)據(jù)內(nèi)容,分配好IP地址,發(fā)送回去一個(gè)"DHCP響應(yīng)"數(shù)據(jù)包。這個(gè)響應(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(接收方),分配給請(qǐng)求端的IP地址和本網(wǎng)絡(luò)的具體參數(shù)則包含在Data部分。
新加入的計(jì)算機(jī)收到這個(gè)響應(yīng)包,于是就知道了自己的IP地址、子網(wǎng)掩碼、網(wǎng)關(guān)地址、DNS服務(wù)器等等參數(shù)。
上網(wǎng)設(shè)置:小結(jié)
這個(gè)部分,需要記住的就是一點(diǎn):不管是"靜態(tài)IP地址"還是"動(dòng)態(tài)IP地址",電腦上網(wǎng)的首要步驟,是確定四個(gè)參數(shù)。這四個(gè)值很重要,值得重復(fù)一遍:
(1) 機(jī)的IP地址
(2) 子網(wǎng)掩碼
(3) 網(wǎng)關(guān)的IP地址
(4) DNS的IP地址
有了這幾個(gè)數(shù)值,電腦就可以上網(wǎng)"沖浪"了。接下來,我們來看一個(gè)實(shí)例,當(dāng)用戶訪問網(wǎng)頁(yè)的時(shí)候,互聯(lián)網(wǎng)協(xié)議是怎么運(yùn)作的。
3、一個(gè)實(shí)例:訪問網(wǎng)頁(yè)
本機(jī)參數(shù)
我們假定,經(jīng)過上一節(jié)的步驟,用戶設(shè)置好了自己的網(wǎng)絡(luò)參數(shù):
(1) 本機(jī)的IP地址:192.168.1.100
(2) 子網(wǎng)掩碼:255.255.255.0
(3) 網(wǎng)關(guān)的IP地址:192.168.1.1
(4) DNS的IP地址:8.8.8.8
然后他打開瀏覽器,想要訪問Google,在地址欄輸入了網(wǎng)址:www.google.com。

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

然后,DNS服務(wù)器做出響應(yīng),告訴我們Google的IP地址是172.194.72.105。于是,我們知道了對(duì)方的IP地址。
子網(wǎng)掩碼
接下來,我們要判斷,這個(gè)IP地址是不是在同一個(gè)子網(wǎng)絡(luò),這就要用到子網(wǎng)掩碼。
已知子網(wǎng)掩碼是255.255.255.0,本機(jī)用它對(duì)自己的IP地址192.168.1.100,做一個(gè)二進(jìn)制的AND運(yùn)算(兩個(gè)數(shù)位都為1,結(jié)果為1,否則為0),計(jì)算結(jié)果為192.168.1.0;然后對(duì)Google的IP地址172.194.72.105也做一個(gè)AND運(yùn)算,計(jì)算結(jié)果為172.194.72.0。這兩個(gè)結(jié)果不相等,所以結(jié)論是,Google與本機(jī)不在同一個(gè)子網(wǎng)絡(luò)。
因此,我們要向Google發(fā)送數(shù)據(jù)包,必須通過網(wǎng)關(guān)192.168.1.1轉(zhuǎn)發(fā),也就是說,接收方的MAC地址將是網(wǎng)關(guān)的MAC地址。
應(yīng)用層協(xié)議
瀏覽網(wǎng)頁(yè)用的是HTTP協(xié)議,它的整個(gè)數(shù)據(jù)包構(gòu)造是這樣的:
HTTP部分的內(nèi)容,類似于下面這樣:
GET?/?HTTP/1.1
Host:?www.google.com
Connection:?keep-alive
User-Agent:?Mozilla/5.0?(Windows?NT?6.1)?......
Accept:?text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:?gzip,deflate,sdch
Accept-Language:?zh-CN,zh;q=0.8
Accept-Charset:?GBK,utf-8;q=0.7,*;q=0.3
Cookie:?...?...
我們假定這個(gè)部分的長(zhǎng)度為4960字節(jié),它會(huì)被嵌在TCP數(shù)據(jù)包之中。
TCP協(xié)議
TCP數(shù)據(jù)包需要設(shè)置端口,接收方(Google)的HTTP端口默認(rèn)是80,發(fā)送方(本機(jī))的端口是一個(gè)隨機(jī)生成的1024-65535之間的整數(shù),假定為51775。
TCP數(shù)據(jù)包的標(biāo)頭長(zhǎng)度為20字節(jié),加上嵌入HTTP的數(shù)據(jù)包,總長(zhǎng)度變?yōu)?980字節(jié)。
IP協(xié)議
然后,TCP數(shù)據(jù)包再嵌入IP數(shù)據(jù)包。IP數(shù)據(jù)包需要設(shè)置雙方的IP地址,這是已知的,發(fā)送方是192.168.1.100(本機(jī)),接收方是172.194.72.105(Google)。
IP數(shù)據(jù)包的標(biāo)頭長(zhǎng)度為20字節(jié),加上嵌入的TCP數(shù)據(jù)包,總長(zhǎng)度變?yōu)?000字節(jié)。
以太網(wǎng)協(xié)議
最后,IP數(shù)據(jù)包嵌入以太網(wǎng)數(shù)據(jù)包。以太網(wǎng)數(shù)據(jù)包需要設(shè)置雙方的MAC地址,發(fā)送方為本機(jī)的網(wǎng)卡MAC地址,接收方為網(wǎng)關(guān)192.168.1.1的MAC地址(通過ARP協(xié)議得到)。
以太網(wǎng)數(shù)據(jù)包的數(shù)據(jù)部分,最大長(zhǎng)度為1500字節(jié),而現(xiàn)在的IP數(shù)據(jù)包長(zhǎng)度為5000字節(jié)。因此,IP數(shù)據(jù)包必須分割成四個(gè)包。因?yàn)槊總€(gè)包都有自己的IP標(biāo)頭(20字節(jié)),所以四個(gè)包的IP數(shù)據(jù)包的長(zhǎng)度分別為1500、1500、1500、560。


服務(wù)器端響應(yīng)
經(jīng)過多個(gè)網(wǎng)關(guān)的轉(zhuǎn)發(fā),Google的服務(wù)器172.194.72.105,收到了這四個(gè)以太網(wǎng)數(shù)據(jù)包。
根據(jù)IP標(biāo)頭的序號(hào),Google將四個(gè)包拼起來,取出完整的TCP數(shù)據(jù)包,然后讀出里面的"HTTP請(qǐng)求",接著做出"HTTP響應(yīng)",再用TCP協(xié)議發(fā)回來。
本機(jī)收到HTTP響應(yīng)以后,就可以將網(wǎng)頁(yè)顯示出來,完成一次網(wǎng)絡(luò)通信。

這個(gè)例子就到此為止,雖然經(jīng)過了簡(jiǎn)化,但它大致上反映了互聯(lián)網(wǎng)協(xié)議的整個(gè)通信過程。
END
《大廠逆襲之路》第一期系列文
