1.這篇文章不是本人原創(chuàng)的骗奖,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的熔吗,在此鄭重地向本文所引用文章的真正作者-----CSDN 博客-Goodboy1881先生致以我崇高的敬意和十二分的感謝
2.轉(zhuǎn)載聲明:本文雖然不是本人100%原創(chuàng)镇饺,但也是辛辛苦苦整理的匙睹,可以轉(zhuǎn)載异剥,但請(qǐng)注明出處
個(gè)人認(rèn)為瑟由,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是他個(gè)人的筆記冤寿,而且歹苦,很遺憾的是這個(gè)系列的博客并沒有更新完,但是這個(gè)系列的博客對(duì)我們這些讀者具有非常大的啟迪作用督怜。
我想殴瘦,這一系列的博客對(duì)于我們這些讀者更大的意義在于:這可以當(dāng)作我們?nèi)ラ喿x、學(xué)習(xí)《TCP/IP協(xié)議詳解》這一本經(jīng)典的提綱吧号杠!
首先蚪腋,TCP/IP不是一個(gè)協(xié)議,而是一個(gè)協(xié)議族的統(tǒng)稱姨蟋。
里面包括了IP協(xié)議屉凯,IMCP協(xié)議,TCP協(xié)議眼溶,以及http悠砚、ftp、pop3協(xié)議等等偷仿。
TCP/IP協(xié)議分層
提到協(xié)議分層哩簿,我們很容易聯(lián)想到ISO-OSI的七層協(xié)議經(jīng)典架構(gòu)宵蕉,但是TCP/IP協(xié)議族的結(jié)構(gòu)則稍有不同。如圖所示
TCP/IP協(xié)議族按照層次由上到下节榜,層層包裝羡玛。
第一層就是應(yīng)用層,這里面有http宗苍,ftp,等等我們熟悉的協(xié)議稼稿。
第二層是傳輸層,著名的TCP和UDP協(xié)議就在這個(gè)層次讳窟。
第三層是網(wǎng)絡(luò)層让歼,IP協(xié)議就在這里,它負(fù)責(zé)對(duì)數(shù)據(jù)加上IP地址和其他的數(shù)據(jù)以確定傳輸?shù)哪繕?biāo)丽啡。
第四層是數(shù)據(jù)鏈路層谋右,這個(gè)層次為待傳送的數(shù)據(jù)加入一個(gè)以太網(wǎng)協(xié)議頭,并進(jìn)行CRC編碼补箍,為最后的數(shù)據(jù)傳輸做準(zhǔn)備改执。
再往下則是硬件層次,負(fù)責(zé)網(wǎng)絡(luò)的傳輸坑雅,這個(gè)層次的定義包括網(wǎng)線的制式辈挂,網(wǎng)卡的定義等等,故有些書并不將這個(gè)層次放在TCP/IP協(xié)議族里面裹粤,因?yàn)樗鼛缀鹾蚑CP/IP協(xié)議的編寫者沒有任何的關(guān)系终蒂。發(fā)送協(xié)議的主機(jī)從上自下將數(shù)據(jù)按照協(xié)議封裝,而接收數(shù)據(jù)的主機(jī)則按照協(xié)議從得到的數(shù)據(jù)包解開遥诉,最后拿到需要的數(shù)據(jù)拇泣。這種結(jié)構(gòu)非常有棧的味道,故某些文章亦將TCP/IP協(xié)議族稱為TCP/IP協(xié)議棧突那。
一些基本的常識(shí)
在學(xué)習(xí)協(xié)議之前挫酿,我們應(yīng)該具備一些如下的基本知識(shí)。
互聯(lián)網(wǎng)地址(IP地址)
網(wǎng)絡(luò)上每一個(gè)節(jié)點(diǎn)都必須有一個(gè)獨(dú)立的Internet地址(也叫做IP地址)愕难。
現(xiàn)在,通常使用的IP地址是一個(gè)32bit的數(shù)字惫霸,也就是我們常說的IPv4標(biāo)準(zhǔn)葫督,這32bit的數(shù)字分成四組永票,也就是常見的255.255.255.255的樣式。
IPv4標(biāo)準(zhǔn)上,地址被分為五類躲庄,我們常用的是B類地址。具體的分類請(qǐng)參考其他文檔低飒。需要注意的是IP地址是網(wǎng)絡(luò)號(hào)+主機(jī)號(hào)的組合。
域名系統(tǒng)
域名系統(tǒng)是一個(gè)分布的數(shù)據(jù)庫藏杖,它提供將主機(jī)名(即網(wǎng)址)轉(zhuǎn)換成IP地址的服務(wù)。
RFC
RFC是什么脉顿?RFC就是tcp/ip協(xié)議的標(biāo)準(zhǔn)文檔蝌麸,在這里我們可以看到RFC那長(zhǎng)長(zhǎng)的定義列表,現(xiàn)在它一共有4000多個(gè)協(xié)議的定義艾疟,當(dāng)然来吩,我們所要學(xué)習(xí)的,也就是那么十幾個(gè)協(xié)議而已蔽莱。
端口號(hào)(port)
注意弟疆,這個(gè)號(hào)碼是用在TCP,UDP上的一個(gè)邏輯號(hào)碼盗冷,并不是一個(gè)硬件端口怠苔,我們平時(shí)說把某某端口封掉了,也只是在IP層次把帶有這個(gè)號(hào)碼的IP包給過濾掉了而已仪糖。
應(yīng)用編程接口
現(xiàn)在常用的編程接口有socket和TLI柑司。
數(shù)據(jù)鏈路層
數(shù)據(jù)鏈路層有三個(gè)目的:
- 為IP模塊發(fā)送和接收IP數(shù)據(jù)報(bào)。
- 為ARP模塊發(fā)送ARP請(qǐng)求和接收ARP應(yīng)答乓诽。
- 為RARP發(fā)送RARP請(qǐng) 求和接收RARP應(yīng)答帜羊。
IP大家都聽說過。至于ARP和RARP鸠天,ARP叫做地址解析協(xié)議讼育,是用IP地址換MAC地址的一種協(xié)議,而RARP則叫做逆地址解析協(xié)議(在局域網(wǎng)中用ARP協(xié)議可以很容易使網(wǎng)絡(luò)癱瘓)稠集。
數(shù)據(jù)鏈路層的協(xié)議還是很多的奶段,有我們最常用的以太網(wǎng)協(xié)議,也有不太常見的令牌環(huán)剥纷,還有FDDI痹籍,當(dāng)然,還有國(guó)內(nèi)現(xiàn)在相當(dāng)普及的PPP協(xié)議(就是adsl寬帶)晦鞋,以及一個(gè)loopback協(xié)議蹲缠。
聯(lián)系linux里面的ifconfig -a命令,這個(gè)命令通常會(huì)得到如下的結(jié)果:
eth0 Link encap:Ethernet HWaddr 00:01:4A:03:5B:ED
inet addr:192.168.11.2 Bcast:192.168.11.25 Mask:255.255.255.0
inet6 addr: fe80::201:4aff:fe03:5bed/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2819 errors:0 dropped:0 overruns:0 frame:0
TX packets:76 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:241609 (235.9 KiB) TX bytes:9596 (9.3 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:2713 errors:0 dropped:0 overruns:0 frame:0
TX packets:2713 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3516032 (3.3 MiB) TX bytes:3516032 (3.3 MiB)
其中悠垛,eth0就是以太網(wǎng)接口线定,而lo則是loopback接口。這也說明這個(gè)主機(jī)在網(wǎng)絡(luò)鏈路層上至少支持loopback協(xié)議和以太網(wǎng)協(xié)議确买。
以太網(wǎng)(Ether-net)的定是指數(shù)字設(shè)備公司( Digital Equipment Corp.)斤讥、英特爾公司(Intel Corp.)和Xerox公司在1982年聯(lián)合公布的一個(gè)標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)里面使用了一種稱作CSMA/CD的接入方法湾趾。而IEEE802提供的標(biāo)準(zhǔn)集802.3(還有一部分定義到了802.2中)也提供了一個(gè)CSMA/CD的標(biāo)準(zhǔn)芭商。
這兩個(gè)標(biāo)準(zhǔn)稍有不同派草,TCP/IP協(xié)議對(duì)這種情況的處理方式如下:
以太網(wǎng)的IP數(shù)據(jù)報(bào)封裝在RFC894中定義,而IEEE802網(wǎng)絡(luò)的IP數(shù)據(jù)報(bào)封裝在RFC1042中定義铛楣。
- 一臺(tái)主機(jī)一定要能發(fā)送和接收RFC894定義的數(shù)據(jù)報(bào)近迁。
- 一臺(tái)主機(jī)可以接收RFC894和RFC1042的封裝格式的混合數(shù)據(jù)報(bào)。
- 一臺(tái)主機(jī)也許能夠發(fā)送RFC1042數(shù)據(jù)報(bào)蛉艾。
如果主機(jī)能同時(shí)發(fā)送兩種類型的分組數(shù)據(jù)钳踊,那么發(fā)送的分組必須是可以設(shè)置的,而且默認(rèn)條件下必須是RFC 894分組勿侯。
可見拓瞪,RFC1042在TCP/IP里面處于一個(gè)配角的地位。這兩種不同的數(shù)據(jù)報(bào)格式請(qǐng)參考教材助琐。
ppp(點(diǎn)對(duì)點(diǎn)協(xié)議)是從SLIP的替代品祭埂。
他們都提供了一種低速接入的解決方案。而每一種數(shù)據(jù)鏈路層協(xié)議兵钮,都有一個(gè)MTU(最大傳輸單元)定義蛆橡,在這個(gè)定義下面,如果IP數(shù)據(jù)報(bào)過大掘譬,則要進(jìn)行分片(fragmentation)泰演,使得每片都小于MTU,注意PPP的MTU并不是一個(gè)物理定義葱轩,而是指一個(gè)邏輯定義(個(gè)人認(rèn)為就是用程序控制)睦焕。
可以用netstat來打印出MTU的結(jié)果,比如鍵入netstat -in
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 1774 0 0 0 587 0 0 0 BMRU
lo 16436 0 2667 0 0 0 2667 0 0 0 LRU
就可以觀察到eth0的MTU是1500靴拱。而lo(環(huán)回接口)的MTU則是16436垃喊。
最后說說那個(gè)環(huán)回接口(loopback)。平時(shí)我們用127.0.0.1來嘗試自己的機(jī)器服務(wù)器好使不好使袜炕。走的就是這個(gè)loopback接口本谜。
對(duì)于環(huán)回接口,有如下三點(diǎn)值得注意:
- 傳給環(huán)回地址(一般是127.0.0.1)的任何數(shù)據(jù)均作為IP輸入偎窘。
- 傳給廣播地址或多播地址的數(shù)據(jù)報(bào)復(fù)制一份傳給環(huán)回接口乌助,然后送到以太網(wǎng)上。這是因?yàn)?strong>廣播傳送和多播傳送的定義包含主機(jī)本身陌知。
- 任何傳給該主機(jī)IP地址的數(shù)據(jù)均送到環(huán)回接口眷茁。
IP協(xié)議,ARP協(xié)議, RARP 協(xié)議
把這三個(gè)協(xié)議放到一起學(xué)習(xí)是因?yàn)檫@三個(gè)協(xié)議處于同一層,ARP協(xié)議用來找到目標(biāo)主機(jī)的Ethernet網(wǎng)卡Mac地址纵诞,IP則承載要發(fā)送的消息。
數(shù)據(jù)鏈路層可以從ARP得到數(shù)據(jù)的傳送信息培遵,而從IP得到要傳輸?shù)臄?shù)據(jù)信息浙芙。
1.IP協(xié)議
IP協(xié)議是TCP/IP協(xié)議的核心登刺,所有的TCP,UDP嗡呼,IMCP纸俭,IGCP的數(shù)據(jù)都以IP數(shù)據(jù)格式傳輸。
要注意的是南窗,IP不是可靠的協(xié)議揍很,這是說,IP協(xié)議沒有提供一種數(shù)據(jù)未傳達(dá)以后的處理機(jī)制--這被認(rèn)為是上層協(xié)議--TCP或UDP要做的事情万伤。因而出現(xiàn)了TCP是一個(gè)可靠的協(xié)議窒悔,而UDP就沒有那么可靠的區(qū)別。
1.1.IP協(xié)議頭
如圖所示
挨個(gè)解釋它是教科書的活計(jì)敌买,我感興趣的只是那八位的TTL字段简珠,還記得這個(gè)字段是做什么的么?
這個(gè)字段規(guī)定該數(shù)據(jù)包在穿過多少個(gè)路由之后才會(huì)被拋棄(這里就體現(xiàn)出來IP協(xié)議包的不可靠性虹钮,它不保證數(shù)據(jù)被送達(dá))聋庵,某個(gè)ip數(shù)據(jù)包每穿過一個(gè)路由器,該數(shù)據(jù)包的TTL數(shù)值就會(huì)減少1芙粱,當(dāng)該數(shù)據(jù)包的TTL成為零祭玉,它就會(huì)被自動(dòng)拋棄。這個(gè)字段的最大值也就是255春畔,也就是說一個(gè)協(xié)議包也就在路由器里面穿行255次就會(huì)被拋棄了脱货,根據(jù)系統(tǒng)的不同,這個(gè)數(shù)字也不一樣拐迁,一般是32或者是64蹭劈。
Tracerouter這個(gè)工具就是用這個(gè)原理工作的,tranceroute的-m選項(xiàng)要求最大值是255线召,也就是因?yàn)檫@個(gè)TTL在IP協(xié)議里面只有8bit铺韧。
現(xiàn)在的IP版本號(hào)是4,所以也稱作IPv4』貉停現(xiàn)在還有IPv6哈打,而且運(yùn)用也越來越廣泛了。
1.2.IP路由選擇
當(dāng)一個(gè)IP數(shù)據(jù)包準(zhǔn)備好了的時(shí)候讯壶,IP數(shù)據(jù)包(或者說是路由器)是如何將數(shù)據(jù)包送到目的地的呢料仗?它是怎么選擇一個(gè)合適的路徑來"送貨"的呢?
- 最特殊的情況是目的主機(jī)和主機(jī)直連伏蚊,那么主機(jī)根本不用尋找路由立轧,可以直接把數(shù)據(jù)傳遞過去。至于是怎么直接傳遞的,這就要靠ARP協(xié)議了氛改,后面會(huì)講到帐萎。
- 稍微一般一點(diǎn)的情況是,主機(jī)通過若干個(gè)路由器(router)和目的主機(jī)連接胜卤。那么路由器就要通過ip包的信息來為ip包尋找到一個(gè)合適的目標(biāo)來進(jìn)行傳遞疆导,比如合適的主機(jī),或者合適的路由葛躏。路由器或者主機(jī)將會(huì)用如下的方式來處理某一個(gè)IP數(shù)據(jù)包:
- 如果IP數(shù)據(jù)包的TTL(生命周期)已到澈段,則該IP數(shù)據(jù)包就被拋棄。
- 搜索路由表舰攒,優(yōu)先搜索匹配主機(jī)败富,如果能找到和IP地址完全一致的目標(biāo)主機(jī),則將該包發(fā)向目標(biāo)主機(jī)芒率。
- 搜索路由表囤耳,如果匹配主機(jī)失敗,則匹配同子網(wǎng)的路由器偶芍,這需要“子網(wǎng)掩碼(1.3.)”的協(xié)助充择。如果找到路由器,則將該包發(fā)向路由器匪蟀。
- 搜索路由表温自,如果匹配同子網(wǎng)路由器失敗波岛,則匹配同網(wǎng)號(hào)路由器笋敞,如果找到路由器觉痛,則將該包發(fā)向路由器。
- 搜索路由表段化,如果以上都失敗了嘁捷,就搜索默認(rèn)路由,如果默認(rèn)路由存在显熏,則發(fā)包雄嚣。
- 如果都失敗了,就丟掉這個(gè)包喘蟆。
這再一次證明了缓升,IP包是不可靠的。因?yàn)樗槐WC送達(dá)蕴轨。
1.3.子網(wǎng)尋址
IP地址的定義是網(wǎng)絡(luò)號(hào)+主機(jī)號(hào)港谊。
但是現(xiàn)在所有的主機(jī)都要求子網(wǎng)編址,也就是說橙弱,把主機(jī)號(hào)在細(xì)分成子網(wǎng)號(hào)+主機(jī)號(hào)歧寺。最終一個(gè)IP地址就成為網(wǎng)絡(luò)號(hào)碼+子網(wǎng)號(hào)+主機(jī)號(hào)燥狰。例如一個(gè)B類地址:210.30.109.134。一般情況下成福,這個(gè)IP地址的紅色部分就是網(wǎng)絡(luò)號(hào)碾局,而藍(lán)色部分就是子網(wǎng)號(hào),綠色部分就是主機(jī)號(hào)奴艾。至于有多少位代表子網(wǎng)號(hào)這個(gè)問題上,這沒有一個(gè)硬性的規(guī)定内斯,取而代之的則是子網(wǎng)掩碼蕴潦,校園網(wǎng)相信大多數(shù)人都用過,在校園網(wǎng)的設(shè)定里面有一個(gè)255.255.255.0的東西俘闯,這就是子網(wǎng)掩碼潭苞。
子網(wǎng)掩碼是由32bit的二進(jìn)制數(shù)字序列,形式為是一連串的1和一連串的0。
例如:
255.255.255.0(二進(jìn)制就是11111111.11111111.11111111.00000000)對(duì)于剛才的那個(gè)B類地址真朗,因?yàn)?10.30是網(wǎng)絡(luò)號(hào)此疹,那么后面的109.134就是子網(wǎng)號(hào)和主機(jī)號(hào)的組合,又因?yàn)?strong>子網(wǎng)掩碼只有后八bit為0遮婶,所以主機(jī)號(hào)就是IP地址的后八個(gè)bit蝗碎,就是134,而剩下的就是子網(wǎng)號(hào)碼--109旗扑。
2. ARP協(xié)議
還記得數(shù)據(jù)鏈路層的以太網(wǎng)的協(xié)議中蹦骑,每一個(gè)數(shù)據(jù)包都有一個(gè)MAC地址頭么?我們知道每一塊以太網(wǎng)卡都有一個(gè)MAC地址臀防,這個(gè)地址是唯一的眠菇,那么IP包是如何知道這個(gè)MAC地址的?這就是ARP協(xié)議的工作袱衷。
ARP(地址解析)協(xié)議是一種解析協(xié)議捎废,本來主機(jī)是完全不知道這個(gè)IP對(duì)應(yīng)的是哪個(gè)主機(jī)的哪個(gè)接口,當(dāng)主機(jī)要發(fā)送一個(gè)IP包的時(shí)候致燥,會(huì)首先查一下自己的ARP高速緩存(就是一個(gè)IP-MAC地址對(duì)應(yīng)表緩存)登疗,如果查詢的IP-MAC值對(duì)不存在,那么主機(jī)就向網(wǎng)絡(luò)發(fā)送一個(gè)ARP協(xié)議廣播包篡悟,這個(gè)廣播包里面就有待查詢的IP地址谜叹,而直接收到這份廣播的包的所有主機(jī)都會(huì)查詢自己的IP地址,如果收到廣播包的某一個(gè)主機(jī)發(fā)現(xiàn)自己符合條件搬葬,那么就準(zhǔn)備好一個(gè)包含自己的MAC地址的ARP包傳送給發(fā)送ARP廣播的主機(jī)荷腊,而廣播主機(jī)拿到ARP包后會(huì)更新自己的ARP緩存(就是存放IP-MAC對(duì)應(yīng)表的地方)。發(fā)送廣播的主機(jī)就會(huì)用新的ARP緩存數(shù)據(jù)準(zhǔn)備好數(shù)據(jù)鏈路層的的數(shù)據(jù)包發(fā)送工作急凰。
一個(gè)典型的arp緩存信息如下女仰,在任意一個(gè)系統(tǒng)里面用“arp -a”命令:
Interface: 192.168.11.3 --- 0x2
Internet Address Physical Address Type
192.168.11.1 00-0d-0b-43-a0-2f dynamic
192.168.11.2 00-01-4a-03-5b-ea dynamic
都會(huì)得到這樣的結(jié)果猜年。
這樣的高速緩存是有時(shí)限的,一般是20分鐘(伯克利系統(tǒng)的衍生系統(tǒng))疾忍。
3.RARP協(xié)議(略)
ICMP協(xié)議乔外,ping和Traceroute
1.IMCP協(xié)議介紹
前面講到了,IP協(xié)議并不是一個(gè)可靠的協(xié)議一罩,它不保證數(shù)據(jù)被送達(dá)杨幼,那么,自然的聂渊,保證數(shù)據(jù)送達(dá)的工作應(yīng)該由其他的模塊來完成差购。其中一個(gè)重要的模塊就是ICMP(網(wǎng)絡(luò)控制報(bào)文)協(xié)議。
當(dāng)傳送IP數(shù)據(jù)包發(fā)生錯(cuò)誤——比如主機(jī)不可達(dá)汉嗽,路由不可達(dá)等等欲逃,ICMP協(xié)議將會(huì)把錯(cuò)誤信息封包,然后傳送回給主機(jī)饼暑。給主機(jī)一個(gè)處理錯(cuò)誤的機(jī)會(huì)稳析,這也就是為什么說建立在IP層以上的協(xié)議是可能做到安全的原因。ICMP數(shù)據(jù)包由8bit的錯(cuò)誤類型和8bit的代碼和16bit的校驗(yàn)和組成弓叛。而前16bit就組成了ICMP所要傳遞的信息彰居。
書上的圖6-3清楚的給出了錯(cuò)誤類型和代碼的組合代表的意思。
盡管在大多數(shù)情況下邪码,錯(cuò)誤的包傳送應(yīng)該給出ICMP報(bào)文裕菠,但是在特殊情況下,是不產(chǎn)生ICMP錯(cuò)誤報(bào)文的闭专。如下:
- ICMP差錯(cuò)報(bào)文不會(huì)產(chǎn)生ICMP差錯(cuò)報(bào)文(出IMCP查詢報(bào)文)(防止IMCP的無限產(chǎn)生和傳送)
- 目的地址是廣播地址或多播地址的IP數(shù)據(jù)報(bào)奴潘。
- 作為鏈路層廣播的數(shù)據(jù)報(bào)。
- 不是IP分片的第一片影钉。
- 源地址不是單個(gè)主機(jī)的數(shù)據(jù)報(bào)画髓。這就是說,源地址不能為零地址平委、環(huán)回地址奈虾、廣播地 址或多播地址。
雖然里面的一些規(guī)定現(xiàn)在還不是很明白廉赔,但是所有的這一切規(guī)定肉微,都是為了防止產(chǎn)生ICMP報(bào)文的無限傳播而定義的。
ICMP協(xié)議大致分為兩類蜡塌,一種是查詢報(bào)文碉纳,一種是差錯(cuò)報(bào)文。其中查詢報(bào)文有以下幾種用途:
- ping查詢
- 子網(wǎng)掩碼查詢(用于無盤工作站在初始化自身的時(shí)候初始化子網(wǎng)掩碼)
- 時(shí)間戳查詢(同步時(shí)間)
而差錯(cuò)報(bào)文則產(chǎn)生在數(shù)據(jù)傳送發(fā)生錯(cuò)誤的時(shí)候馏艾。就不贅述了劳曹。
2.ICMP的應(yīng)用--ping
ping可以說是ICMP的最著名的應(yīng)用奴愉,當(dāng)我們某一個(gè)網(wǎng)站上不去的時(shí)候。通常會(huì)ping一下這個(gè)網(wǎng)站铁孵。ping會(huì)回顯出一些有用的信息锭硼。一般的信息如下:
Reply from 10.4.24.1: bytes=32 time<1ms TTL=255
Reply from 10.4.24.1: bytes=32 time<1ms TTL=255
Reply from 10.4.24.1: bytes=32 time<1ms TTL=255
Reply from 10.4.24.1: bytes=32 time<1ms TTL=255
Ping statistics for 10.4.24.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
ping這個(gè)單詞源自聲納定位,而這個(gè)程序的作用也確實(shí)如此蜕劝,它利用ICMP協(xié)議包來偵測(cè)另一個(gè)主機(jī)是否可達(dá)檀头。原理是用類型碼為0的ICMP發(fā)請(qǐng)求,受到請(qǐng)求的主機(jī)則用類型碼為8的ICMP回應(yīng)熙宇。ping程序來計(jì)算間隔時(shí)間鳖擒,并計(jì)算有多少個(gè)包被送達(dá)。用戶就可以判斷網(wǎng)絡(luò)大致的情況烫止。我們可以看到,ping給出來了傳送的時(shí)間和TTL的數(shù)據(jù)戳稽。我給的例子不太好馆蠕,因?yàn)樽叩穆酚缮伲信d趣地可以ping一下國(guó)外的網(wǎng)站比如sf.net惊奇,就可以觀察到一些丟包的現(xiàn)象互躬,而程序運(yùn)行的時(shí)間也會(huì)更加的長(zhǎng)。
ping還給我們一個(gè)看主機(jī)到目的主機(jī)的路由的機(jī)會(huì)颂郎。這是因?yàn)椋?strong>ICMP的ping請(qǐng)求數(shù)據(jù)報(bào)在每經(jīng)過一個(gè)路由器的時(shí)候吼渡,路由器都會(huì)把自己的ip放到該數(shù)據(jù)報(bào)中。而目的主機(jī)則會(huì)把這個(gè)ip列表復(fù)制到回應(yīng)icmp數(shù)據(jù)包中發(fā)回給主機(jī)乓序。但是寺酪,無論如何,ip頭所能紀(jì)錄的路由列表是非常的有限替劈。如果要觀察路由寄雀, 我們還是需要使用更好的工具,就是要講到的Traceroute(windows下面的名字叫做tracert)陨献。
3.ICMP的應(yīng)用--Traceroute
Traceroute是用來偵測(cè)主機(jī)到目的主機(jī)之間所經(jīng)路由情況的重要工具盒犹,也是最便利的工具。前面說到眨业,盡管ping工具也可以進(jìn)行偵測(cè)急膀,但是,因?yàn)閕p頭的限制龄捡,ping不能完全的記錄下所經(jīng)過的路由器卓嫂。而Traceroute正好填補(bǔ)了這個(gè)缺憾。
Traceroute的原理是非常非常的有意思墅茉,它受到目的主機(jī)的IP后命黔,首先給目的主機(jī)發(fā)送一個(gè)TTL=1的UDP數(shù)據(jù)包呜呐,而經(jīng)過的第一個(gè)路由器收到這個(gè)數(shù)據(jù)包以后,就自動(dòng)把TTL減1悍募,而TTL變?yōu)?以后蘑辑,路由器就把這個(gè)包給拋棄了,并同時(shí)產(chǎn)生 一個(gè)主機(jī)不可達(dá)的ICMP數(shù)據(jù)報(bào)給主機(jī)坠宴。主機(jī)收到這個(gè)數(shù)據(jù)報(bào)以后再發(fā)一個(gè)TTL=2的UDP數(shù)據(jù)報(bào)給目的主機(jī)洋魂,然后刺激第二個(gè)路由器給主機(jī)發(fā)ICMP數(shù)據(jù) 報(bào)。如此往復(fù)直到到達(dá)目的主機(jī)喜鼓。這樣副砍,traceroute就拿到了所有的路由器ip。從而避開了ip頭只能記錄有限路由IP的問題庄岖。
那怎么知道UDP到?jīng)]到達(dá)目的主機(jī)呢铣卡?這就涉及一個(gè)技巧的問題,TCP和UDP協(xié)議有一個(gè)端口號(hào)定義裙士,而普通的網(wǎng)絡(luò)程序只監(jiān)控少數(shù)的幾個(gè)號(hào)碼較 小的端口征堪,比如說80,比如說23,等等。而traceroute發(fā)送的是端口號(hào)>30000(真變態(tài))的UDP報(bào)背桐,所以到達(dá)目的主機(jī)的時(shí)候优烧,目的 主機(jī)只能發(fā)送一個(gè)端口不可達(dá)的ICMP數(shù)據(jù)報(bào)給主機(jī)。主機(jī)接到這個(gè)報(bào)告以后就知道链峭,主機(jī)到了畦娄,所以說Traceroute是個(gè)騙子一點(diǎn)也不為過:)
Traceroute程序里面提供了一些很有用的選項(xiàng),甚至包含了IP選路的選項(xiàng)弊仪,請(qǐng)察看man文檔來了解這些熙卡,不贅述。
IP選路撼短,動(dòng)態(tài)選路再膳,和一些細(xì)節(jié)
1.靜態(tài)IP選路
1.1.一個(gè)簡(jiǎn)單的路由表
選路是IP層最重要的一個(gè)功能之一。前面的部分已經(jīng)簡(jiǎn)單的講過路由器是通過何種規(guī)則來根據(jù)IP數(shù)據(jù)包的IP地址來選擇路由曲横。這里就不重復(fù)了喂柒。首先來看看一個(gè)簡(jiǎn)單的系統(tǒng)路由表。
Destination Gateway Genmask Flags Metric RefIface
192.168.11.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.11.1 0.0.0.0 UG 0 0 0 eth0
對(duì)于一個(gè)給定的路由器禾嫉,可以打印出五種不同的flag灾杰。
- U表明該路由可用。
- G表明該路由是到一個(gè)網(wǎng)關(guān)熙参。如果沒有這個(gè)標(biāo)志艳吠,說明和Destination是直連的,而相應(yīng)的Gateway應(yīng)該直接給出Destination的地址孽椰。
- H表明該路由是到一個(gè)主機(jī)昭娩,如果沒有該標(biāo)志凛篙,說明Destination是一個(gè)網(wǎng)絡(luò),換句話說Destination就應(yīng)該寫成一個(gè)網(wǎng)絡(luò)號(hào)和子網(wǎng)號(hào)的組合栏渺,而不包括主機(jī)號(hào)(主機(jī)號(hào)碼處為0)呛梆,例如 192.168.11.0
- D表明該路由是為重定向報(bào)文創(chuàng)建的
- M該路由已經(jīng)被重定向報(bào)文修改
U沒啥可說的,G說明這是一個(gè)網(wǎng)關(guān)磕诊,如果你要發(fā)數(shù)據(jù)給Destination填物,IP頭應(yīng)該寫Destination的IP地址,而數(shù)據(jù)鏈路層的MAC地址就應(yīng)該是GateWay的Mac地址了霎终;反之滞磺,如果沒有G標(biāo)志,那么數(shù)據(jù)鏈路層和IP層的地址應(yīng)該是對(duì)應(yīng)的莱褒。H說明了Destination的性質(zhì)击困,如果是H的,則說明該地址是一個(gè)完整的地址广凸,既有網(wǎng)絡(luò)號(hào)又有主機(jī)號(hào)沛励,那么再匹配的時(shí)候就既要匹配網(wǎng)絡(luò)號(hào),又要匹配主機(jī)號(hào)炮障;反之,Destination就代表一個(gè)網(wǎng)絡(luò)坤候,在匹配的時(shí)候只要匹配一下網(wǎng)絡(luò)號(hào)就可以了胁赢。
這樣,IP選路的方式就可以更加具體化了白筹。如下
首先用IP地址來匹配那些帶H標(biāo)志的DestinationIP地址智末。
如果1失敗就匹配那些網(wǎng)絡(luò)地址。
如果2失敗就發(fā)送到Default網(wǎng)關(guān)
順便提一下那個(gè)GenMask徒河,它指定了目的地址的子網(wǎng)號(hào)系馆,例如第一條的子網(wǎng)就是11。
1.2.其他有關(guān)路由表的知識(shí)
一般顽照,我們?cè)谂渲煤靡粋€(gè)網(wǎng)絡(luò)接口的時(shí)候由蘑,一個(gè)路由就被直接創(chuàng)建好了。當(dāng)然我們也可以手動(dòng)添加路由代兵。用route add命令就可以了尼酿。
而當(dāng)一個(gè)IP包在某一個(gè)路由器的時(shí)候發(fā)現(xiàn)沒有路由可走,那么該路由器就會(huì)給源主機(jī)發(fā)送“主機(jī)不可達(dá)”或者“網(wǎng)絡(luò)不可達(dá)”的ICMP包來報(bào)錯(cuò)植影。
注意裳擎,一般的操作系統(tǒng)默認(rèn)是沒有路由功能的,這需要自己配置思币。這些歷史原因就不細(xì)說了鹿响,
1.3.ICMP的IP重定向報(bào)文和路由發(fā)現(xiàn)報(bào)文
當(dāng)IP包在某一個(gè)地方轉(zhuǎn)向的時(shí)候羡微,都回給發(fā)送IP報(bào)的源主機(jī)一個(gè)ICMP重定向報(bào)文,而源主機(jī)就可以利用這個(gè)信息來更新自己的路由表惶我,這樣妈倔,隨著網(wǎng)絡(luò)通信的逐漸增多,路由表也就越來越完備指孤,數(shù)據(jù)轉(zhuǎn)發(fā)的速度也會(huì)越來越快启涯。我們需要注意的是:
重定向報(bào)文只能由路由器發(fā)出。
重定向報(bào)文為主機(jī)所用恃轩,而不是為路由器所用结洼。
在主機(jī)引導(dǎo)的時(shí)候,一般會(huì)發(fā)送在網(wǎng)內(nèi)廣播一個(gè)路由請(qǐng)求的ICMP報(bào)文叉跛,而多個(gè)路由器則會(huì)回應(yīng)一個(gè)路由通告報(bào)文松忍。而且,路由其本身不定期的在網(wǎng)絡(luò)內(nèi)發(fā)布路由通告報(bào)文筷厘,這樣鸣峭,根據(jù)這些報(bào)文,每一個(gè)主機(jī)都會(huì)有機(jī)會(huì)建立自己的路由表而實(shí)現(xiàn)網(wǎng)絡(luò)通信酥艳。路由器在一份通告報(bào)文中可以通告多個(gè)地址摊溶,并且給出每一個(gè)地址的優(yōu)先等級(jí),這個(gè)優(yōu)先等級(jí)是該IP作為默認(rèn)路由的等級(jí)充石,至于怎么算的就不深究了莫换。
路由器一般會(huì)在450-600秒的時(shí)間間隔內(nèi)發(fā)布一次通告,而一個(gè)給定的通告報(bào)文的壽命是30分鐘骤铃。而主機(jī)在引導(dǎo)的時(shí)候會(huì)每三秒發(fā)送一次請(qǐng)求報(bào)文拉岁,一旦接受到一個(gè)有效的通告報(bào)文,就停止發(fā)送請(qǐng)求報(bào)文惰爬。
在TCP/IP詳解編寫的時(shí)候喊暖,只有Solaris2.x支持這兩種報(bào)文,大多數(shù)系統(tǒng)還不支持這兩種報(bào)文撕瞧。(后面還會(huì)講到一些有用的路由報(bào)文)
動(dòng)態(tài)選路協(xié)議
前面的選路方法叫做靜態(tài)選路陵叽,簡(jiǎn)要地說就是在配置接口的時(shí)候,以默認(rèn)的方式生成路由表項(xiàng)风范。并通過route來增加表項(xiàng)咨跌,或者通過ICMP報(bào)文來更新表項(xiàng)(通常在默認(rèn)方式出錯(cuò)的情況下)。 而如果上訴三種方法都不能滿足硼婿,那么我們就使用動(dòng)態(tài)選路锌半。
動(dòng)態(tài)選路協(xié)議是用于動(dòng)態(tài)選路的重要組成部分,但是他們只是使用在路由器之間,相鄰路由器之間互相通信刊殉。系統(tǒng)(路由選擇程序)選擇比較合適的路有放到核心路由表中殉摔,然后系統(tǒng)就可以根據(jù)這個(gè)核心路有表找到最合適的網(wǎng)路。也就是說记焊,動(dòng)態(tài)選路是在系統(tǒng)核心網(wǎng)絡(luò)外部進(jìn)行的逸月,它只是用一些選路的策略影響路由表,而不會(huì)影響到最后通過路由表選擇路由的那一部分遍膜。選路協(xié)議有一大類常用的叫做內(nèi)部網(wǎng)關(guān)協(xié)議(IGP)碗硬,而在IGP中,RIP就是其中最重要的協(xié)議瓢颅。一種新的IGP協(xié)議叫做開放最短路經(jīng)優(yōu)先(OSPF)協(xié)議恩尾,其意在取代RIP。另一種最早用在網(wǎng)路骨干網(wǎng)上的IGP協(xié)議--HELLO挽懦,現(xiàn)在已經(jīng)不用了翰意。
如今,任何支持動(dòng)態(tài)選路的路由器都必須同時(shí)支持OSPF和RIP信柿,還可以選擇性的支持其他的IGP協(xié)議冀偶。
2.1.Unix選路程序
Unix系統(tǒng)上面通常都有路由守護(hù)程序--routed。還有一個(gè)叫做gate渔嚷。gate所支持的協(xié)議要比routed多进鸠,routed只是支持RIPv1版本。而gate則支持RIPv1形病、v2堤如,BGPv1 等等。
2.1.RIP:選路信息協(xié)議
它的定義可以在RFC1058內(nèi)找到窒朋,這種協(xié)議使用UDP作為載體(也就是UDP的上層協(xié)議)。我們最關(guān)心的就是RIP其中的一個(gè)段蝗岖,叫做度量的段侥猩,這是一個(gè)以hop作為計(jì)數(shù)器(就是以走過多少路由為計(jì)數(shù)器)的段(IP協(xié)議里面也有一個(gè)TTL)。這個(gè)度量段將最終影響到路由表的建立抵赢。參考圖:
一般說來routed要承擔(dān)如下的工作:
給每一個(gè)已知的路由器發(fā)送rip請(qǐng)求報(bào)文欺劳,要求其他路由器給出完整的路由表。這種報(bào)文的命令字段為1铅鲤,地址字段為0划提,度量地段為16(相當(dāng)于無窮大)。
接受請(qǐng)求邢享,如果接收到剛才的那個(gè)請(qǐng)求鹏往,就把自己的完整的路由表交給請(qǐng)求者。如果沒有骇塘,就處理IP請(qǐng)求表項(xiàng)伊履,把表項(xiàng)中自己有的部分添上跳數(shù)韩容,沒有的部分添上16。然后發(fā)給請(qǐng)求者唐瀑。
接受回應(yīng)群凶。更新自己的路由表。使用hop數(shù)小的規(guī)則哄辣。
定期更新路由表请梢,一般是 30s 給相鄰的路由啟發(fā)一次自己的路由表。這種形式可以是廣播形式的力穗。
這個(gè)協(xié)議看起來會(huì)工作的很好毅弧,但是,這里面其實(shí)有很多隱藏的憂患睛廊,比如說RIP沒有子網(wǎng)的概念脑题,比如說環(huán)路的危險(xiǎn)其徙。而且hop數(shù)的上限也限制了網(wǎng)絡(luò)的大小。
因此,出現(xiàn)了很多RIPv1的替代品躬审,比如說RIPv2,比如說OSPF。他們都是通過某種策略來影響路由表溯捆,所以就不說了仲墨。
UDP協(xié)議
1.UDP簡(jiǎn)要介紹
UDP是傳輸層協(xié)議,和TCP協(xié)議處于一個(gè)分層中疏遏,但是與TCP協(xié)議不同脉课,UDP協(xié)議并不提供超時(shí)重傳,出錯(cuò)重傳等功能财异,也就是說其是不可靠的協(xié)議倘零。
2.UDP協(xié)議頭
2.1.UDP端口號(hào)
由于很多軟件需要用到UDP協(xié)議,所以UDP協(xié)議必須通過某個(gè)標(biāo)志用以區(qū)分不同的程序所需要的數(shù)據(jù)包戳寸。端口號(hào)的功能就在于此呈驶,例如某一個(gè)UDP程序A在系統(tǒng)中注冊(cè)了3000端口,那么疫鹊,以后從外面?zhèn)鬟M(jìn)來的目的端口號(hào)為3000的UDP包都會(huì)交給該程序袖瞻。端口號(hào)理論上可以有2^16這么多。因?yàn)樗拈L(zhǎng)度是16個(gè)bit
2.2.UDP檢驗(yàn)和
這是一個(gè)可選的選項(xiàng)拆吆,并不是所有的系統(tǒng)都對(duì)UDP數(shù)據(jù)包加以檢驗(yàn)和數(shù)據(jù)(相對(duì)TCP協(xié)議的必須來說)聋迎,但是RFC中標(biāo)準(zhǔn)要求,發(fā)送端應(yīng)該計(jì)算檢驗(yàn)和枣耀。
UDP檢驗(yàn)和覆蓋UDP協(xié)議頭和數(shù)據(jù)霉晕,這和IP的檢驗(yàn)和是不同的,IP協(xié)議的檢驗(yàn)和只是覆蓋IP數(shù)據(jù)頭,并不覆蓋所有的數(shù)據(jù)娄昆。UDP和TCP都包含一個(gè)偽首部佩微,這是為了計(jì)算檢驗(yàn)和而攝制的。偽首部甚至還包含IP地址這樣的IP協(xié)議里面都有的信息萌焰,目的是讓UDP兩次檢查數(shù)據(jù)是否已經(jīng)正確到達(dá)目的地哺眯。如果發(fā)送端沒有打開檢驗(yàn)和選項(xiàng),而接收端計(jì)算檢驗(yàn)和有差錯(cuò)扒俯,那么UDP數(shù)據(jù)將會(huì)被悄悄的丟掉(不保證送達(dá))奶卓,而不產(chǎn)生任何差錯(cuò)報(bào)文。
2.3.UDP長(zhǎng)度
UDP可以很長(zhǎng)很長(zhǎng)撼玄,可以有65535字節(jié)那么長(zhǎng)夺姑。但是一般網(wǎng)絡(luò)在傳送的時(shí)候,一次一般傳送不了那么長(zhǎng)的協(xié)議(涉及到MTU的問題)掌猛,就只好對(duì)數(shù)據(jù)分片盏浙,當(dāng)然,這些是對(duì)UDP等上級(jí)協(xié)議透明的荔茬,UDP不需要關(guān)心IP協(xié)議層對(duì)數(shù)據(jù)如何分片废膘,下一個(gè)章節(jié)將會(huì)稍微討論一些分片的策略。
IP分片
IP在從上層接到數(shù)據(jù)以后慕蔚,要根據(jù)IP地址來判斷從那個(gè)接口發(fā)送數(shù)據(jù)(通過選路)丐黄,并進(jìn)行MTU的查詢,如果數(shù)據(jù)大小超過MTU就進(jìn)行數(shù)據(jù)分片孔飒。數(shù)據(jù)的分片是對(duì)上層和下層透明灌闺,而數(shù)據(jù)也只是到達(dá)目的地還會(huì)被重新組裝,不過不用擔(dān)心坏瞄,IP層提供了足夠的信息進(jìn)行數(shù)據(jù)的再組裝桂对。
在IP頭里面,16bit識(shí)別號(hào)唯一記錄了一個(gè)IP包的ID,具有同一個(gè)ID的IP片將會(huì)被重新組裝鸠匀;而13位片偏移則記錄了某IP片相對(duì)整個(gè)包的位置接校;而這兩個(gè)表示中間的3bit標(biāo)志則標(biāo)示著該分片后面是否還有新的分片。這三個(gè)標(biāo)示就組成了IP分片的所有信息狮崩,接受方就可以利用這些信息對(duì)IP數(shù)據(jù)進(jìn)行重新組織(就算是后面的分片比前面的分片先到,這些信息也是足夠了)鹿寻。
因?yàn)榉制夹g(shù)在網(wǎng)絡(luò)上被經(jīng)常的使用睦柴,所以偽造IP分片包進(jìn)行流氓攻擊的軟件和人也就層出不窮。
可以用Trancdroute程序來進(jìn)行簡(jiǎn)單的MTU偵測(cè)毡熏。請(qǐng)參看教材坦敌。
3.UDP和ARP之間的交互式用
這是不常被人注意到的一個(gè)細(xì)節(jié),這是針對(duì)一些系統(tǒng)地實(shí)現(xiàn)來說的。當(dāng)ARP緩存還是空的時(shí)候狱窘。UDP在被發(fā)送之前一定要發(fā)送一個(gè)ARP請(qǐng)求來獲得目的主機(jī)的MAC地址杜顺,如果這個(gè)UDP的數(shù)據(jù)包足夠大,大到IP層一定要對(duì)其進(jìn)行分片的時(shí)候蘸炸,想象中躬络,該UDP數(shù)據(jù)包的第一個(gè)分片會(huì)發(fā)出一個(gè)ARP查詢請(qǐng)求,所有的分片都非等到這個(gè)查詢完成以后再發(fā)送搭儒。事實(shí)上是這樣嗎穷当?
結(jié)果是,某些系統(tǒng)會(huì)讓每一個(gè)分片都發(fā)送一個(gè)ARP查詢淹禾,所有的分片都在等待馁菜,但是接受到第一個(gè)回應(yīng)的時(shí)候,主機(jī)卻只發(fā)送了最后一個(gè)數(shù)據(jù)片而拋棄了其他铃岔,這實(shí)在是讓人匪夷所思汪疮。這樣,因?yàn)榉制臄?shù)據(jù)不能被及時(shí)組裝毁习,接受主機(jī)將會(huì)在一段時(shí)間內(nèi)將永遠(yuǎn)無法組裝的IP數(shù)據(jù)包拋棄智嚷,并且發(fā)送組裝超時(shí)的ICMP報(bào)文(其實(shí)很多系統(tǒng)不產(chǎn)生這個(gè)差錯(cuò)),以保證接受主機(jī)自己的接收端緩存不被那些永遠(yuǎn)得不到組裝的分片充滿蜓洪。
4.ICMP源站抑制差錯(cuò)
當(dāng)目標(biāo)主機(jī)的處理速度趕不上數(shù)據(jù)接收的速度纤勒,因?yàn)榻邮苤鳈C(jī)的IP層緩存會(huì)被占滿,所以主機(jī)就會(huì)發(fā)出一個(gè)“我受不了”的一個(gè)ICMP報(bào)文隆檀。
5.UDP服務(wù)器設(shè)計(jì)
UDP協(xié)議的某些特性將會(huì)影響我們的服務(wù)器程序設(shè)計(jì)摇天,大致總結(jié)如下:
關(guān)于客戶IP和地址:服務(wù)器必須有根據(jù)客戶IP地址和端口號(hào)判斷數(shù)據(jù)包是否合法的能力(這似乎要求每一個(gè)服務(wù)器都要具備)
關(guān)于目的地址:服務(wù)器必須要有過濾廣播地址的能力。
關(guān)于數(shù)據(jù)輸入:通常服務(wù)器系統(tǒng)的每一個(gè)端口號(hào)都會(huì)和一塊輸入緩沖區(qū)對(duì)應(yīng)恐仑,進(jìn)來的輸入根據(jù)先來后到的原則等待服務(wù)器的處理泉坐,所以難免會(huì)出現(xiàn)緩沖區(qū)溢出的問題,這種情況下裳仆,UDP數(shù)據(jù)包可能會(huì)被丟棄腕让,而應(yīng)用服務(wù)器程序本身并不知道這個(gè)問題。
服務(wù)器應(yīng)該限制本地IP地址歧斟,就是說它應(yīng)該可以把自己綁定到某一個(gè)網(wǎng)絡(luò)接口的某一個(gè)端口上纯丸。
廣播和多播,IGMP協(xié)議
1.單播静袖,多播觉鼻,廣播的介紹
1.1.單播(unicast)
單播是說,對(duì)特定的主機(jī)進(jìn)行數(shù)據(jù)傳送队橙。例如給某一個(gè)主機(jī)發(fā)送IP數(shù)據(jù)包坠陈。這時(shí)候萨惑,數(shù)據(jù)鏈路層給出的數(shù)據(jù)頭里面是非常具體的目的地址,對(duì)于以太網(wǎng)來 說仇矾,就是網(wǎng)卡的MAC地址(不是FF-FF-FF-FF-FF-FF這樣的地址)∮拱現(xiàn)在的具有路由功能的主機(jī)應(yīng)該可以將單播數(shù)據(jù)定向轉(zhuǎn)發(fā),而目的主機(jī)的網(wǎng) 絡(luò)接口則可以過濾掉和自己MAC地址不一致的數(shù)據(jù)贮匕。
1.2.廣播(unicast)
廣播是主機(jī)針對(duì)某一個(gè)網(wǎng)絡(luò)上的所有主機(jī)發(fā)送數(shù)據(jù)包姐仅。這個(gè)網(wǎng)絡(luò)可能是網(wǎng)絡(luò),可能是子網(wǎng)粗合,還可能是所有的子網(wǎng)萍嬉。如果是網(wǎng)絡(luò),例如A類網(wǎng)址的廣播就是 netid.255.255.255隙疚,如果是子網(wǎng)壤追,則是netid.netid.subnetid.255;如果是所有的子網(wǎng)(B類IP)則是則是 netid.netid.255.255供屉。廣播所用的MAC地址FF-FF-FF-FF-FF-FF行冰。網(wǎng)絡(luò)內(nèi)所有的主機(jī)都會(huì)收到這個(gè)廣播數(shù)據(jù),網(wǎng)卡只要把 MAC地址為FF-FF-FF-FF-FF-FF的數(shù)據(jù)交給內(nèi)核就可以了伶丐。一般說來ARP悼做,或者路由協(xié)議RIP應(yīng)該是以廣播的形式播發(fā)的。
1.3.多播(multicast)
可以說廣播是多播的特例哗魂,多播就是給一組特定的主機(jī)(多播組)發(fā)送數(shù)據(jù)肛走,這樣,數(shù)據(jù)的播發(fā)范圍會(huì)小一些(實(shí)際上播發(fā)的范圍一點(diǎn)也沒有變小)录别,多播的MAC地址是最高字節(jié)的低位為一朽色,例 如01-00-00-00-00-00。多播組的地址是D類IP组题,規(guī)定是224.0.0.0-239.255.255.255葫男。
雖然多播較特殊,但是究其原理崔列,多播的數(shù)據(jù)還是要通過數(shù)據(jù)鏈路層進(jìn)行MAC地址綁定然后進(jìn)行發(fā)送梢褐。所以一個(gè)以太網(wǎng)卡在綁定了一個(gè)多播IP地址之后,必定還要綁定一個(gè)多播的MAC地址赵讯,才能使得其可以像單播那樣工作盈咳。這個(gè)多播的IP和多播MAC地址有一個(gè)對(duì)應(yīng)的算法,在書的p133到p134之間边翼∮阆欤可以看到這個(gè)對(duì)應(yīng)不是一一對(duì)應(yīng)的,主機(jī)還是要對(duì)多播數(shù)據(jù)進(jìn)行過濾讯私。
個(gè)人的看法:
廣播和多播的性質(zhì)是一樣的热押,路由器會(huì)把數(shù)據(jù)放到局域網(wǎng)里面,然后網(wǎng)卡對(duì)這些數(shù)據(jù)進(jìn)行過濾斤寇,只拿到自己打算要的數(shù)據(jù)桶癣,比如自己感興趣的多 播數(shù)據(jù),自己感興趣的組播數(shù)據(jù)娘锁。當(dāng)一個(gè)主機(jī)運(yùn)行了一個(gè)處理某一個(gè)多播IP的進(jìn)程的時(shí)候牙寞,這個(gè)進(jìn)程會(huì)給網(wǎng)卡綁定一個(gè)虛擬的多播mac地址,并做出來一個(gè)多播 ip莫秆。這樣间雀,網(wǎng)卡就會(huì)讓帶有這個(gè)多播mac地址的數(shù)據(jù)進(jìn)來,從而實(shí)現(xiàn)通信镊屎,而那些沒有監(jiān)聽這些數(shù)據(jù)的主機(jī)就會(huì)把這些數(shù)據(jù)過濾掉惹挟,換句話說,多播缝驳,是讓主機(jī)的內(nèi)核輕松了连锯,而網(wǎng)卡,對(duì)不起用狱,您就累點(diǎn)吧运怖。
一些文章也印證了這種想法,最明顯的就是局域網(wǎng)監(jiān)聽的原理夏伊、實(shí)現(xiàn)與防范
2.一些驗(yàn)證性實(shí)驗(yàn)
這些實(shí)驗(yàn)并不是很復(fù)雜,我們只是要ping一下一般的ip和一個(gè)廣播地址。首先我ping一下自己所在的子網(wǎng)的某一臺(tái)主機(jī):
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time=1ms TTL=255
可以看到休涤,機(jī)器返回的是一臺(tái)主機(jī)的回應(yīng)結(jié)果敏弃,進(jìn)而推測(cè),如果我ping一個(gè)廣播地址呢砸狞?結(jié)果如下:
Reply from 192.168.11.9: bytes=32 time=1ms TTL=255
Reply from 192.168.11.174: bytes=32 time<1ms TTL=64
Reply from 192.168.11.174: bytes=32 time<1ms TTL=64
Reply from 192.168.11.174: bytes=32 time<1ms TTL=64
Reply from 192.168.11.218: bytes=32 time<1ms TTL=64
Reply from 192.168.11.174: bytes=32 time<1ms TTL=64
可以看到捻勉,ping返回了一些隨機(jī)的ip的結(jié)果,這些ip都是與主機(jī)在同一子網(wǎng)內(nèi)的ip刀森。我們可以看到踱启,廣播實(shí)際上是給處于子網(wǎng)內(nèi)的所有ip發(fā)信。
再來一個(gè)多播的例子研底,但是要實(shí)現(xiàn)這個(gè)多播并不容易埠偿,因?yàn)槲也恢谰W(wǎng)絡(luò)內(nèi)有多少個(gè)多播組,就只好利用幾個(gè)特殊的多播地址來驗(yàn)證了榜晦。
對(duì)于多播地址冠蒋,有幾個(gè)特殊的多播地址被占用,他們是
224.0.0.1--該子網(wǎng)內(nèi)所有的系統(tǒng)組乾胶。
224.0.0.2--該子網(wǎng)內(nèi)所有的路由器抖剿。
224.0.1.1--網(wǎng)絡(luò)實(shí)現(xiàn)協(xié)議NTP專用IP朽寞。
224.0.0.9--RIPv2專用IP
所以只要ping這幾個(gè)IP,就應(yīng)該能得到一些結(jié)果斩郎,比如說我ping 224.0.0.2:
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
Reply from 192.168.11.1: bytes=32 time<1ms TTL=255
我們可以看到脑融,這回ping只返回了一個(gè)ip的回應(yīng)。而這個(gè)就是我的網(wǎng)關(guān)的地址缩宜,這也驗(yàn)證了224.0.0.2是所有路由器的多播(組播)地址
3.IGMP協(xié)議
IGMP的作用在于肘迎,讓其他所有需要知道自己處于哪個(gè)多播組的主機(jī)和路由器知道自己的狀態(tài)。一般多播路由器根本不需要知道某一個(gè)多播組里面有多少個(gè)主機(jī)锻煌,而只要知道自己的子網(wǎng)內(nèi)還有沒有處于某個(gè)多播組的主機(jī)就可以了妓布。只要某一個(gè)多播組還有一臺(tái)主機(jī),多播路由器就會(huì)把數(shù)據(jù)傳輸出去宋梧,這樣匣沼,接受方就會(huì)通過網(wǎng)卡過濾功能來得到自己想要的數(shù)據(jù)。為了知道多播組的信息乃秀,多播路由器需要定時(shí)的發(fā)送IGMP查詢肛著,IGMP的格式可以看書,各個(gè)多播組里面的主機(jī)要根據(jù)查詢來回復(fù)自己的狀態(tài)跺讯。路由器來決定有幾個(gè)多播組枢贿,自己要對(duì)某一個(gè)多播組發(fā)送什么樣的數(shù)據(jù)。
這種查詢回應(yīng)數(shù)據(jù)報(bào)的TTL一般是1刀脏,而且就算是出錯(cuò)也不產(chǎn)生ICMP差錯(cuò)(沒必要)局荚。
DNS域名系統(tǒng)
前面已經(jīng)提到了訪問一臺(tái)機(jī)器要靠IP地址和MAC地址,其中愈污,MAC地址可以通過ARP協(xié)議得到耀态,所以這對(duì)用戶是透明的,但是IP地址就不行暂雹,無論如何用戶都需要用一個(gè)指定的IP來訪問一臺(tái)計(jì)算機(jī)首装,而IP地址又非常不好記,于是就出現(xiàn)了DNS系統(tǒng)杭跪。
1.DNS系統(tǒng)介紹
DNS的全稱是Domain Name System仙逻。它負(fù)責(zé)把FQDN(就是以"."分隔結(jié)尾的名字)翻譯成一個(gè)IP。最初的DNS系統(tǒng)使用的是一個(gè)巨大的hosts.txt文件涧尿,可是一段時(shí)間以后系奉,就不得不用數(shù)據(jù)庫來代替hosts.txt文件,最終發(fā)展到了現(xiàn)在的分布式數(shù)據(jù)庫姑廉。
從書中的143頁可以看到缺亮,DNS系統(tǒng)是一個(gè)巨大的樹,最上方有一個(gè)無名樹根桥言,下一層是arpa,com,edu,gov,int,mil,us, cn萌踱。等等葵礼,其中arpa,是域名反解析樹的頂端并鸵;而com,edu章咧,等域名本來只用在美國(guó)(這就是技術(shù)特權(quán)),但是現(xiàn)在幾乎全世界通用能真;而us, cn扰柠,等叫做國(guó)家域粉铐。
這個(gè)樹里面的域名并不是統(tǒng)一管理的,網(wǎng)絡(luò)信息中心(NIS)負(fù)責(zé)分配頂級(jí)域合委派其他制定地區(qū)域的授權(quán)機(jī)構(gòu)卤档。
一個(gè)獨(dú)立管理的DNS子樹叫做zone蝙泼,最常見的區(qū)域就是二級(jí)域名,比如說.com.cn劝枣。我們還可以把這個(gè)二級(jí)域名給劃分成更小的區(qū)域汤踏,比如說sina.com.cn。
DNS系統(tǒng)是一個(gè)分布式的數(shù)據(jù)庫舔腾,當(dāng)一個(gè)數(shù)據(jù)庫發(fā)現(xiàn)自己并沒有某查詢所需要的數(shù)據(jù)的時(shí)候溪胶,它將把查詢轉(zhuǎn)發(fā)出去,而轉(zhuǎn)發(fā)的目的地通常是根服務(wù)器稳诚,根服務(wù)器從上至下層層轉(zhuǎn)發(fā)查詢哗脖,直到找到目標(biāo)為止。DNS還有一個(gè)特點(diǎn)就是使用高速緩存扳还,DNS把查詢過的數(shù)據(jù)緩存在某處才避,便于下次查詢時(shí)使用。
2.DNS協(xié)議
DNS報(bào)文定義了一個(gè)既可以查詢也可以響應(yīng)的報(bào)文格式氨距。具體格式可以看P145頁桑逝。對(duì)各個(gè)字段簡(jiǎn)單解釋如下
最前面的16個(gè)bit唯一的標(biāo)示了問題號(hào)碼,用于查詢端區(qū)別自己的查詢俏让。
緊接著的16個(gè)bit又可以做進(jìn)一步的細(xì)分楞遏,標(biāo)示了報(bào)文的性質(zhì)和一些細(xì)節(jié),比如說是查詢報(bào)文還是響應(yīng)報(bào)文舆驶,需要遞歸查詢與否(一般服務(wù)器都支持遞歸查詢橱健,而且不需要任何設(shè)置,BIND就是這樣)
查詢問題后面有查詢類型沙廉,包括A拘荡,NS,CNAME撬陵,PTR珊皿,HINFO网缝,MX,如果熟悉BIND的話蟋定,就知道在zong的配置文件里面粉臊,每一條記錄都記載了各自的類型,比如A就是IP地址驶兜,NS就是名字服務(wù)器扼仲。
響應(yīng)報(bào)文可以回復(fù)多個(gè)IP,也就是說抄淑,域名可以和多個(gè)IP地址對(duì)應(yīng)屠凶,并且有很多CNAME。
3.反向查詢
正向查詢指的是通過域名得到IP的查詢肆资,而反向查詢就是通過IP得到域名矗愧。例如用host命令,host ip就可以得到服務(wù)器的域名郑原,host domainName 就得到IP唉韭。
稍微知道一點(diǎn)數(shù)據(jù)結(jié)構(gòu)的人都能意識(shí)到,在正向查詢的域里面做反向查詢犯犁,其做法只有遍歷整個(gè)數(shù)據(jù)集合----對(duì)于DNS來說属愤,那就是遍歷整個(gè)數(shù)據(jù)庫, 這將帶來巨大的負(fù)擔(dān)酸役,所以DNS采取了另一種方法春塌,使用另一棵子樹來維護(hù)IP-〉域名的對(duì)應(yīng)表。這個(gè)子樹的根節(jié)點(diǎn)是in-addr.arpa,而一個(gè)IP 例如192.168.11.2)所具有的DNS地址就是 2.11.168.192.in-addr.arpa(ip倒置)簇捍。在DNS系統(tǒng)里面只壳,一個(gè)反向地址對(duì)應(yīng)一個(gè)PTR紀(jì)錄(對(duì)應(yīng)A紀(jì)錄),所以反向查詢又叫 做指針(PTR)查詢暑塑。
4.其他問題的討論
4.1.DNS服務(wù)器高速緩存
BIND9默認(rèn)是作為一個(gè)高速緩存服務(wù)器吼句,其將所有的查詢都轉(zhuǎn)交到根服務(wù)器去,然后得到結(jié)果并放在本地的緩沖區(qū)事格,以加快查詢速度惕艳。如果有興趣可以安裝一個(gè)BIND9來嘗試一下。而自己定義的zone則可以規(guī)定其在緩存中的時(shí)間驹愚,一般是1天(就是配置文件中的1D)远搪。
4.2.用UDP還是TCP
DNS服務(wù)器支持TCP和UDP兩種協(xié)議的查詢方式,而且端口都是53逢捺。而大多數(shù)的查詢都是UDP查詢的谁鳍,一般需要TCP查詢的有兩種情況:
當(dāng)查詢數(shù)據(jù)多大以至于產(chǎn)生了數(shù)據(jù)截?cái)?TC標(biāo)志為1),這時(shí),需要利用TCP的分片能力來進(jìn)行數(shù)據(jù)傳輸(看TCP的相關(guān)章節(jié))倘潜。
當(dāng)主(master)服務(wù)器和輔(slave)服務(wù)器之間通信绷柒,輔服務(wù)器要拿到主服務(wù)器的zone信息的時(shí)候。
TCP協(xié)議概述
TCP和UDP處在同一層---運(yùn)輸層涮因,但是TCP和UDP最不同的地方是废睦,TCP提供了一種可靠的數(shù)據(jù)傳輸服務(wù),TCP是面向連接的养泡,也就是說嗜湃,利用TCP通信的兩臺(tái)主機(jī)首先要經(jīng)歷一個(gè)“撥打電話”的過程,等到通信準(zhǔn)備結(jié)束才開始傳輸數(shù)據(jù)澜掩,最后結(jié)束通話净蚤。所以TCP要比UDP可靠的多,UDP是把數(shù)據(jù)直接發(fā)出去输硝,而不管對(duì)方是不是在收信,就算是UDP無法送達(dá)程梦,也不會(huì)產(chǎn)生ICMP差錯(cuò)報(bào)文点把,這一經(jīng)時(shí)重申了很多遍了。
把TCP保證可靠性的簡(jiǎn)單工作原理摘抄如下:
應(yīng)用數(shù)據(jù)被分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊屿附。這和UDP完全不同郎逃,應(yīng)用程序產(chǎn)生的數(shù)據(jù)報(bào)長(zhǎng)度將保持不變。由TCP傳遞給IP的信息單位稱為報(bào)文段或段( segment)(參見圖1 - 7)挺份。在1 8.4節(jié)我們將看到TCP如何確定報(bào)文段的長(zhǎng)度褒翰。
當(dāng)TCP發(fā)出一個(gè)段后,它啟動(dòng)一個(gè)定時(shí)器匀泊,等待目的端確認(rèn)收到這個(gè)報(bào)文段优训。如果不能及時(shí)收到一個(gè)確認(rèn),將重發(fā)這個(gè)報(bào)文段各聘。在第21章我們將了解TCP協(xié)議中自適應(yīng)的超時(shí)及重傳策略揣非。
當(dāng)TCP收到發(fā)自TCP連接另一端的數(shù)據(jù),它將發(fā)送一個(gè)確認(rèn)躲因。這個(gè)確認(rèn)不是立即發(fā)送早敬,通常將推遲幾分之一秒,這將在1 9.3節(jié)討論大脉。
TCP將保持它首部和數(shù)據(jù)的檢驗(yàn)和搞监。這是一個(gè)端到端的檢驗(yàn)和,目的是檢測(cè)數(shù)據(jù)在傳輸過程中的任何變化镰矿。如果收到段的檢驗(yàn)和有差錯(cuò)琐驴,TP將丟棄這個(gè)報(bào)文段和不確認(rèn)收到此報(bào)文段(希望發(fā)端超時(shí)并重發(fā))色建。
既然TCP報(bào)文段作為IP數(shù)據(jù)報(bào)來傳輸侥蒙,而IP數(shù)據(jù)報(bào)的到達(dá)可能會(huì)失序,因此TCP報(bào)文段 的到達(dá)也可能會(huì)失序。如果必要障般, TCP將對(duì)收到的數(shù)據(jù)進(jìn)行重新排序,將收到的數(shù)據(jù)以正確的順序交給應(yīng)用層扰魂。
TCP還能提供流量控制肃叶。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)茁帽。這將防止較快主機(jī)致使較慢主機(jī)的緩沖區(qū)溢出玉罐。
從這段話中可以看到,TCP中保持可靠性的方式就是超時(shí)重發(fā)潘拨,這是有道理的吊输,雖然TCP也可以用各種各樣的ICMP報(bào)文來處理這些,但是這也不是可靠的铁追,最可靠的方式就是只要不得到確認(rèn)季蚂,就重新發(fā)送數(shù)據(jù)報(bào),直到得到對(duì)方的確認(rèn)為止琅束。
TCP的首部和UDP首部一樣扭屁,都有發(fā)送端口號(hào)和接收端口號(hào)。但是顯然涩禀,TCP的首部信息要比UDP的多料滥,可以看到,TCP協(xié)議提供了發(fā)送和確認(rèn)所需要的所有必要的信息艾船。這在P171-173有詳細(xì)地介紹葵腹。可以想象一個(gè)TCP數(shù)據(jù)的發(fā)送應(yīng)該是如下的一個(gè)過程屿岂。
雙方建立連接
發(fā)送方給接受方TCP數(shù)據(jù)報(bào)践宴,然后等待對(duì)方的確認(rèn)TCP數(shù)據(jù)報(bào),如果沒有爷怀,就重新發(fā)浴井,如果有,就發(fā)送下一個(gè)數(shù)據(jù)報(bào)霉撵。
接受方等待發(fā)送方的數(shù)據(jù)報(bào)磺浙,如果得到數(shù)據(jù)報(bào)并檢驗(yàn)無誤,就發(fā)送ACK(確認(rèn))數(shù)據(jù)報(bào)徒坡,并等待下一個(gè)TCP數(shù)據(jù)報(bào)的到來撕氧。直到接收到FIN(發(fā)送完成數(shù)據(jù)報(bào))
中止連接
可以想見,為了建立一個(gè)TCP連接喇完,系統(tǒng)可能會(huì)建立一個(gè)新的進(jìn)程(最差也是一個(gè)線程)伦泥,來進(jìn)行數(shù)據(jù)的傳送。
TCP連接的建立與中止
TCP是一個(gè)面向連接的協(xié)議,所以在連接雙方發(fā)送數(shù)據(jù)之前不脯,都需要首先建立一條連接府怯。
這和前面講到的協(xié)議完全不同。前面講的所有協(xié)議都只是發(fā)送數(shù)據(jù)而已防楷,大多數(shù)都不關(guān)心發(fā)送的數(shù)據(jù)是不是送到牺丙,UDP尤其明顯,從編程的角度來說复局,UDP編程也要簡(jiǎn)單的多----UDP都不用考慮數(shù)據(jù)分片冲簿。
書中用telnet登陸退出來解釋TCP協(xié)議連接的建立和中止的過程,可以看到:
TCP連接的建立可以簡(jiǎn)單的稱為三次握手亿昏,而連接的中止則可以叫做四次握手峦剔。
1.連接的建立
在建立連接的時(shí)候,客戶端首先向服務(wù)器申請(qǐng)打開某一個(gè)端口(用SYN段等于1的TCP報(bào)文)角钩,然后服務(wù)器端發(fā)回一個(gè)ACK報(bào)文通知客戶端請(qǐng)求報(bào)文收到吝沫,客戶端收到確認(rèn)報(bào)文以后再次發(fā)出確認(rèn)報(bào)文確認(rèn)剛才服務(wù)器端發(fā)出的確認(rèn)報(bào)文(繞口么),至此递礼,連接的建立完成惨险。這就叫做三次握手。如果打算讓雙方都做好準(zhǔn)備的話宰衙,一定要發(fā)送三次報(bào)文,而且只需要三次報(bào)文就可以了睹欲。
可以想見供炼,如果再加上TCP的超時(shí)重傳機(jī)制,那么TCP就完全可以保證一個(gè)數(shù)據(jù)包被送到目的地窘疮。
2.結(jié)束連接
TCP有一個(gè)特別的概念叫做half-close袋哼,這個(gè)概念是說,TCP的連接是全雙工(可以同時(shí)發(fā)送和接收)連接闸衫,因此在關(guān)閉連接的時(shí)候涛贯,必須關(guān)閉傳和送兩個(gè)方向上的連接∥党觯客戶機(jī)給服務(wù)器一個(gè)FIN為1的TCP報(bào)文弟翘,然后服務(wù)器返回給客戶端一個(gè)確認(rèn)ACK報(bào)文,并且發(fā)送一個(gè)FIN報(bào)文骄酗,當(dāng)客戶機(jī)回復(fù)ACK報(bào)文后(四次握手)稀余,連接就結(jié)束了。
3.最大報(bào)文長(zhǎng)度
在建立連接的時(shí)候趋翻,通信的雙方要互相確認(rèn)對(duì)方的最大報(bào)文長(zhǎng)度(MSS)睛琳,以便通信。一般這個(gè)SYN長(zhǎng)度是MTU減去固定IP首部和TCP首部長(zhǎng)度。對(duì)于一個(gè)以太網(wǎng)师骗,一般可以達(dá)到1460字節(jié)历等。當(dāng)然如果對(duì)于非本地的IP,這個(gè)MSS可能就只有536字節(jié)辟癌,而且寒屯,如果中間的傳輸網(wǎng)絡(luò)的MSS更佳的小的話,這個(gè)值還會(huì)變得更小愿待。
4.TCP的狀態(tài)遷移圖
書P182頁給出了TCP的狀態(tài)圖浩螺,這是一個(gè)看起來比較復(fù)雜的狀態(tài)遷移圖,因?yàn)樗藘蓚€(gè)部分---服務(wù)器的狀態(tài)遷移和客戶端的狀態(tài)遷移仍侥,如果從某一個(gè)角度出發(fā)來看這個(gè)圖要出,就會(huì)清晰許多,這里面的服務(wù)器和客戶端都不是絕對(duì)的农渊,發(fā)送數(shù)據(jù)的就是客戶端患蹂,接受數(shù)據(jù)的就是服務(wù)器。
4.1.客戶端應(yīng)用程序的狀態(tài)遷移圖
客戶端的狀態(tài)可以用如下的流程來表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情況下應(yīng)該有的流程砸紊,從書中的圖中可以看到传于,在建立連接時(shí),當(dāng)客戶端收到SYN報(bào)文的ACK以后醉顽,客戶端就打開了數(shù)據(jù)交互地連接沼溜。而結(jié)束連接則通常是客戶端主動(dòng)結(jié)束的,客戶端結(jié)束應(yīng)用程序以后游添,需要經(jīng)歷FIN_WAIT_1系草,F(xiàn)IN_WAIT_2等狀態(tài),這些狀態(tài)的遷移就是前面提到的結(jié)束連接的四次握手唆涝。
4.2.服務(wù)器的狀態(tài)遷移圖
服務(wù)器的狀態(tài)可以用如下的流程來表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
TCP是一個(gè)面向連接的協(xié)議找都,所以在連接雙方發(fā)送數(shù)據(jù)之前,都需要首先建立一條連接廊酣。
這和前面講到的協(xié)議完全不同能耻。前面講的所有協(xié)議都只是發(fā)送數(shù)據(jù)而已,大多數(shù)都不關(guān)心發(fā)送的數(shù)據(jù)是不是送到亡驰,UDP尤其明顯晓猛,從編程的角度來說,UDP編程也要簡(jiǎn)單的多----UDP都不用考慮數(shù)據(jù)分片凡辱。
書中用telnet登陸退出來解釋TCP協(xié)議連接的建立和中止的過程鞍帝,可以看到:
>TCP連接的建立可以簡(jiǎn)單的稱為三次握手,而連接的中止則可以叫做四次握手煞茫。
### 1.連接的建立
>在建立連接的時(shí)候帕涌,客戶端首先向服務(wù)器申請(qǐng)打開某一個(gè)端口(用SYN段等于1的TCP報(bào)文)摄凡,然后服務(wù)器端發(fā)回一個(gè)ACK報(bào)文通知客戶端請(qǐng)求報(bào)文收到,客戶端收到確認(rèn)報(bào)文以后再次發(fā)出確認(rèn)報(bào)文確認(rèn)剛才服務(wù)器端發(fā)出的確認(rèn)報(bào)文(繞口么)蚓曼,至此亲澡,連接的建立完成。這就叫做三次握手纫版。如果打算讓雙方都做好準(zhǔn)備的話床绪,一定要發(fā)送三次報(bào)文,而且只需要三次報(bào)文就可以了其弊。
可以想見癞己,如果再加上TCP的超時(shí)重傳機(jī)制,那么TCP就完全可以保證一個(gè)數(shù)據(jù)包被送到目的地梭伐。
### 2.結(jié)束連接
>TCP有一個(gè)特別的概念叫做half-close痹雅,這個(gè)概念是說,TCP的連接是全雙工(可以同時(shí)發(fā)送和接收)連接糊识,因此在關(guān)閉連接的時(shí)候绩社,必須關(guān)閉傳和送兩個(gè)方向上的連接÷该纾客戶機(jī)給服務(wù)器一個(gè)FIN為1的TCP報(bào)文愉耙,然后服務(wù)器返回給客戶端一個(gè)確認(rèn)ACK報(bào)文,并且發(fā)送一個(gè)FIN報(bào)文拌滋,當(dāng)客戶機(jī)回復(fù)ACK報(bào)文后(四次握手)朴沿,連接就結(jié)束了。
### 3.最大報(bào)文長(zhǎng)度
>在建立連接的時(shí)候败砂,通信的雙方要互相確認(rèn)對(duì)方的最大報(bào)文長(zhǎng)度(MSS)赌渣,以便通信。一般這個(gè)SYN長(zhǎng)度是MTU減去固定IP首部和TCP首部長(zhǎng)度吠卷。對(duì)于一個(gè)以太網(wǎng)锡垄,一般可以達(dá)到1460字節(jié)沦零。當(dāng)然如果對(duì)于非本地的IP祭隔,這個(gè)MSS可能就只有536字節(jié),而且路操,如果中間的傳輸網(wǎng)絡(luò)的MSS更佳的小的話疾渴,這個(gè)值還會(huì)變得更小。
### 4.TCP的狀態(tài)遷移圖
>書P182頁給出了TCP的狀態(tài)圖屯仗,這是一個(gè)看起來比較復(fù)雜的狀態(tài)遷移圖搞坝,因?yàn)樗藘蓚€(gè)部分---服務(wù)器的狀態(tài)遷移和客戶端的狀態(tài)遷移,如果從某一個(gè)角度出發(fā)來看這個(gè)圖魁袜,就會(huì)清晰許多桩撮,這里面的服務(wù)器和客戶端都不是絕對(duì)的敦第,發(fā)送數(shù)據(jù)的就是客戶端,接受數(shù)據(jù)的就是服務(wù)器店量。
>##### 4.1.客戶端應(yīng)用程序的狀態(tài)遷移圖
>>客戶端的狀態(tài)可以用如下的流程來表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情況下應(yīng)該有的流程芜果,從書中的圖中可以看到,在建立連接時(shí)融师,當(dāng)客戶端收到SYN報(bào)文的ACK以后右钾,客戶端就打開了數(shù)據(jù)交互地連接。而結(jié)束連接則通常是客戶端主動(dòng)結(jié)束的旱爆,客戶端結(jié)束應(yīng)用程序以后舀射,需要經(jīng)歷FIN_WAIT_1,F(xiàn)IN_WAIT_2等狀態(tài)怀伦,這些狀態(tài)的遷移就是前面提到的結(jié)束連接的四次握手脆烟。
>##### 4.2.服務(wù)器的狀態(tài)遷移圖
>>服務(wù)器的狀態(tài)可以用如下的流程來表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
在建立連接的時(shí)候,服務(wù)器端是在第三次握手之后才進(jìn)入數(shù)據(jù)交互狀態(tài)空镜,而關(guān)閉連接則是在關(guān)閉連接的第二次握手以后(注意不是第四次)浩淘。而關(guān)閉以后還要等待客戶端給出最后的ACK包才能進(jìn)入初始的狀態(tài)。
4.3.其他狀態(tài)遷移
書中的圖還有一些其他的狀態(tài)遷移吴攒,這些狀態(tài)遷移針對(duì)服務(wù)器和客戶端兩方面的總結(jié)如下
LISTEN->SYN_SENT张抄,對(duì)于這個(gè)解釋就很簡(jiǎn)單了,服務(wù)器有時(shí)候也要打開連接的嘛洼怔。
SYN_SENT->SYN收到署惯,服務(wù)器和客戶端在SYN_SENT狀態(tài)下如果收到SYN數(shù)據(jù)報(bào)钥飞,則都需要發(fā)送SYN的ACK數(shù)據(jù)報(bào)并把自己的狀態(tài)調(diào)整到SYN收到狀態(tài)搬素,準(zhǔn)備進(jìn)入ESTABLISHED
SYN_SENT->CLOSED,在發(fā)送超時(shí)的情況下碘赖,會(huì)返回到CLOSED狀態(tài)安岂。
SYN_收到->LISTEN轻猖,如果受到RST包,會(huì)返回到LISTEN狀態(tài)域那。
SYN_收到->FIN_WAIT_1咙边,這個(gè)遷移是說,可以不用到ESTABLISHED狀態(tài)次员,而可以直接跳轉(zhuǎn)到FIN_WAIT_1狀態(tài)并等待關(guān)閉败许。
4.4. 2MSL等待狀態(tài)
書中給的圖里面,有一個(gè)TIME_WAIT等待狀態(tài)淑蔚,這個(gè)狀態(tài)又叫做2MSL狀態(tài)市殷,說的是在TIME_WAIT2發(fā)送了最后一個(gè)ACK數(shù)據(jù)報(bào)以后,要進(jìn)入TIME_WAIT狀態(tài)刹衫,這個(gè)狀態(tài)是防止最后一次握手的數(shù)據(jù)報(bào)沒有傳送到對(duì)方那里而準(zhǔn)備的(注意這不是四次握手醋寝,這是第四次握手的保險(xiǎn)狀態(tài))搞挣。這個(gè)狀態(tài)在很大程度上保證了雙方都可以正常結(jié)束,但是音羞,問題也來了柿究。
由于插口的2MSL狀態(tài)(插口是IP和端口對(duì)的意思,socket)黄选,使得應(yīng)用程序在2MSL時(shí)間內(nèi)是無法再次使用同一個(gè)插口的蝇摸,對(duì)于客戶程序還好一些,但是對(duì)于服務(wù)程序办陷,例如httpd貌夕,它總是要使用同一個(gè)端口來進(jìn)行服務(wù),而在2MSL時(shí)間內(nèi)民镜,啟動(dòng)httpd就會(huì)出現(xiàn)錯(cuò)誤(插口被使用)啡专。為了避免這個(gè)錯(cuò)誤,服務(wù)器給出了一個(gè)平靜時(shí)間的概念制圈,這是說在2MSL時(shí)間內(nèi)们童,雖然可以重新啟動(dòng)服務(wù)器,但是這個(gè)服務(wù)器還是要平靜的等待2MSL時(shí)間的過去才能進(jìn)行下一次連接鲸鹦。
4.5.FIN_WAIT_2狀態(tài)
這就是著名的半關(guān)閉的狀態(tài)了慧库,這是在關(guān)閉連接時(shí),客戶端和服務(wù)器兩次握手之后的狀態(tài)馋嗜。在這個(gè)狀態(tài)下齐板,應(yīng)用程序還有接受數(shù)據(jù)的能力,但是已經(jīng)無法發(fā)送數(shù)據(jù)葛菇,但是也有一種可能是甘磨,客戶端一直處于FIN_WAIT_2狀態(tài),而服務(wù)器則一直處于WAIT_CLOSE狀態(tài)眯停,而直到應(yīng)用層來決定關(guān)閉這個(gè)狀態(tài)济舆。
5.RST,同時(shí)打開和同時(shí)關(guān)閉
RST是另一種關(guān)閉連接的方式莺债,應(yīng)用程序應(yīng)該可以判斷RST包的真實(shí)性滋觉,即是否為異常中止。而同時(shí)打開和同時(shí)關(guān)閉則是兩種特殊的TCP狀態(tài)九府,發(fā)生的概率很小椎瘟。
6.TCP服務(wù)器設(shè)計(jì)
前面曾經(jīng)講述過UDP的服務(wù)器設(shè)計(jì)覆致,可以發(fā)現(xiàn)UDP的服務(wù)器完全不需要所謂的并發(fā)機(jī)制侄旬,它只要建立一個(gè)數(shù)據(jù)輸入隊(duì)列就可以。但是TCP不同煌妈,TCP服務(wù)器對(duì)于每一個(gè)連接都需要建立一個(gè)獨(dú)立的進(jìn)程(或者是輕量級(jí)的儡羔,線程)宣羊,來保證對(duì)話的獨(dú)立性。所以TCP服務(wù)器是并發(fā)的汰蜘。而且TCP還需要配備一個(gè)呼入連接請(qǐng)求隊(duì)列(UDP服務(wù)器也同樣不需要)仇冯,來為每一個(gè)連接請(qǐng)求建立對(duì)話進(jìn)程,這也就是為什么各種TCP服務(wù)器都有一個(gè)最大連接數(shù)的原因族操。而根據(jù)源主機(jī)的IP和端口號(hào)碼苛坚,服務(wù)器可以很輕松的區(qū)別出不同的會(huì)話,來進(jìn)行數(shù)據(jù)的分發(fā)色难。
掌握本章的狀態(tài)遷移圖才是學(xué)習(xí)本章的關(guān)鍵泼舱。
TCP交互數(shù)據(jù)流,成塊數(shù)據(jù)流
目前建立在TCP協(xié)議上的網(wǎng)絡(luò)協(xié)議特別多枷莉,有telnet娇昙,ssh,有ftp笤妙,有http等等冒掌。這些協(xié)議又可以根據(jù)數(shù)據(jù)吞吐量來大致分成兩大類:
(1)交互數(shù)據(jù)類型,例如telnet蹲盘,ssh股毫,這種類型的協(xié)議在大多數(shù)情況下只是做小流量的數(shù)據(jù)交換,比如說按一下鍵盤召衔,回顯一些文字等等皇拣。
(2)數(shù)據(jù)成塊類型,例如ftp薄嫡,這種類型的協(xié)議要求TCP能盡量的運(yùn)載數(shù)據(jù)氧急,把數(shù)據(jù)的吞吐量做到最大,并盡可能的提高效率毫深。針對(duì)這兩種情況吩坝,TCP給出了兩種不同的策略來進(jìn)行數(shù)據(jù)傳輸。
1.TCP的交互數(shù)據(jù)流
對(duì)于交互性要求比較高的應(yīng)用哑蔫,TCP給出兩個(gè)策略來提高發(fā)送效率和減低網(wǎng)絡(luò)負(fù)擔(dān):
- 捎帶ACK钉寝。
- Nagle算法(一次盡量多的發(fā)數(shù)據(jù))。
通常闸迷,在網(wǎng)絡(luò)速度很快的情況下嵌纲,比如用lo接口進(jìn)行telnet通信,當(dāng)按下字母鍵并要求回顯的時(shí)候腥沽,客戶端和服務(wù)器將經(jīng)歷 發(fā)送按鍵數(shù)據(jù)->服務(wù)器發(fā)送按鍵數(shù)據(jù)的ack -> 服務(wù)器端發(fā)送回顯數(shù)據(jù)->客戶端發(fā)送回顯數(shù)據(jù)的ACK的過程逮走,而其中的數(shù)據(jù)流量將是40bit + 41bit+41bit+40bit = 162bit,如果在廣域網(wǎng)里面今阳,這種小分組的TCP流量將會(huì)造成很大的網(wǎng)絡(luò)負(fù)擔(dān)师溅。
1.1.捎帶ACK的發(fā)送方式
這個(gè)策略是說茅信,當(dāng)主機(jī)收到遠(yuǎn)程主機(jī)的TCP數(shù)據(jù)報(bào)之后,通常不馬上發(fā)送ACK數(shù)據(jù)報(bào)墓臭,而是等上一個(gè)短暫的時(shí)間蘸鲸,如果這段時(shí)間里面主機(jī)還有發(fā)送到遠(yuǎn)程主機(jī)的TCP數(shù)據(jù)報(bào),那么就把這個(gè)ACK數(shù)據(jù)報(bào)“捎帶”著發(fā)送出去窿锉,把本來兩個(gè)TCP數(shù)據(jù)報(bào)整合成一個(gè)發(fā)送酌摇。一般的,這個(gè)時(shí)間是200ms嗡载∶畋裕可以明顯地看到這個(gè)策略可以把TCP數(shù)據(jù)報(bào)的利用率提高很多。
1.2.Nagle算法
上過bbs的人應(yīng)該都會(huì)有感受鼻疮,就是在網(wǎng)絡(luò)慢的時(shí)候發(fā)貼怯伊,有時(shí)鍵入一串字符串以后,經(jīng)過一段時(shí)間判沟,客戶端“發(fā)瘋”一樣突然回顯出很多內(nèi)容耿芹,就好像數(shù)據(jù)一下子傳過來了一樣,這就是Nagle算法的作用挪哄。
Nagle算法是說吧秕,當(dāng)主機(jī)A給主機(jī)B發(fā)送了一個(gè)TCP數(shù)據(jù)報(bào)并進(jìn)入等待主機(jī)B的ACK數(shù)據(jù)報(bào)的狀態(tài)時(shí),TCP的輸出緩沖區(qū)里面只能有一個(gè)TCP數(shù)據(jù)報(bào)迹炼,并且砸彬,這個(gè)數(shù)據(jù)報(bào)不斷地收集后來的數(shù)據(jù),整合成一個(gè)大的數(shù)據(jù)報(bào)斯入,等到B主機(jī)的ACK包一到砂碉,就把這些數(shù)據(jù)“一股腦”的發(fā)送出去。
雖然這樣的描述有些不準(zhǔn)確刻两,但還算形象和易于理解增蹭,我們同樣可以體會(huì)到這個(gè)策略對(duì)于低減網(wǎng)絡(luò)負(fù)擔(dān)的好處。
在編寫插口程序的時(shí)候磅摹,可以通過TCP_NODELAY來關(guān)閉這個(gè)算法滋迈。并且,使用這個(gè)算法看情況的户誓,比如基于TCP的X窗口協(xié)議饼灿,如果處理鼠標(biāo)事件時(shí)還是用這個(gè)算法,那么“延遲”可就非常大了帝美。
2.TCP的成塊數(shù)據(jù)流
對(duì)于FTP這樣對(duì)于數(shù)據(jù)吞吐量有較高要求的要求碍彭,將總是希望每次盡量多的發(fā)送數(shù)據(jù)到對(duì)方主機(jī),就算是有點(diǎn)“延遲”也無所謂。TCP也提供了一整套的策略來支持這樣的需求硕旗。TCP協(xié)議中有16個(gè)bit表示“窗口”的大小,這是這些策略的核心女责。
2.1.傳輸數(shù)據(jù)時(shí)ACK的問題
在解釋滑動(dòng)窗口前漆枚,需要看看ACK的應(yīng)答策略,一般來說抵知,發(fā)送端發(fā)送一個(gè)TCP數(shù)據(jù)報(bào)墙基,那么接收端就應(yīng)該發(fā)送一個(gè)ACK數(shù)據(jù)報(bào)。但是事實(shí)上卻不是這樣刷喜,發(fā)送端將會(huì)連續(xù)發(fā)送數(shù)據(jù)盡量填滿接受方的緩沖區(qū)残制,而接受方對(duì)這些數(shù)據(jù)只要發(fā)送一個(gè)ACK報(bào)文來回應(yīng)就可以了,這就是ACK的累積特性掖疮,這個(gè)特性大大減少了發(fā)送端和接收端的負(fù)擔(dān)初茶。
2.2.滑動(dòng)窗口
滑動(dòng)窗口本質(zhì)上是描述接受方的TCP數(shù)據(jù)報(bào)緩沖區(qū)大小的數(shù)據(jù),發(fā)送方根據(jù)這個(gè)數(shù)據(jù)來計(jì)算自己最多能發(fā)送多長(zhǎng)的數(shù)據(jù)浊闪。如果發(fā)送方收到接受方的窗口大小為0的TCP數(shù)據(jù)報(bào)恼布,那么發(fā)送方將停止發(fā)送數(shù)據(jù),等到接受方發(fā)送窗口大小不為0的數(shù)據(jù)報(bào)的到來搁宾。
書中的P211和P212很好的解釋了這一點(diǎn)折汞。
關(guān)于滑動(dòng)窗口協(xié)議,書上還介紹了三個(gè)術(shù)語盖腿,分別是:
窗口合攏:當(dāng)窗口從左邊向右邊靠近的時(shí)候爽待,這種現(xiàn)象發(fā)生在數(shù)據(jù)被發(fā)送和確認(rèn)的時(shí)候。
窗口張開:當(dāng)窗口的右邊沿向右邊移動(dòng)的時(shí)候翩腐,這種現(xiàn)象發(fā)生在接受端處理了數(shù)據(jù)以后鸟款。
窗口收縮:當(dāng)窗口的右邊沿向左邊移動(dòng)的時(shí)候,這種現(xiàn)象不常發(fā)生茂卦。
TCP就是用這個(gè)窗口欠雌,慢慢的從數(shù)據(jù)的左邊移動(dòng)到右邊,把處于窗口范圍內(nèi)的數(shù)據(jù)發(fā)送出去(但不用發(fā)送所有疙筹,只是處于窗口內(nèi)的數(shù)據(jù)可以發(fā)送富俄。)。這就是窗口的意義而咆。圖20-6解釋了這一點(diǎn)霍比。窗口的大小是可以通過socket來制定的,4096并不是最理想的窗口大小暴备,而16384則可以使吞吐量大大的增加悠瞬。
2.3.數(shù)據(jù)擁塞
上面的策略用于局域網(wǎng)內(nèi)傳輸還可以,但是用在廣域網(wǎng)中就可能會(huì)出現(xiàn)問題,最大的問題就是當(dāng)傳輸時(shí)出現(xiàn)了瓶頸(比如說一定要經(jīng)過一個(gè)slip低速鏈路)所產(chǎn)生的大量數(shù)據(jù)堵塞問題(擁塞)浅妆,為了解決這個(gè)問題望迎,TCP發(fā)送方需要確認(rèn)連接雙方的線路的數(shù)據(jù)最大吞吐量是多少。這凌外,就是所謂的擁塞窗口辩尊。
擁塞窗口的原理很簡(jiǎn)單,TCP發(fā)送方首先發(fā)送一個(gè)數(shù)據(jù)報(bào)康辑,然后等待對(duì)方的回應(yīng)摄欲,得到回應(yīng)后就把這個(gè)窗口的大小加倍,然后連續(xù)發(fā)送兩個(gè)數(shù)據(jù)報(bào)疮薇,等到對(duì)方回應(yīng)以后胸墙,再把這個(gè)窗口加倍(先是2的指數(shù)倍,到一定程度后就變成現(xiàn)行增長(zhǎng)按咒,這就是所謂的慢啟動(dòng))迟隅,發(fā)送更多的數(shù)據(jù)報(bào)喇辽,直到出現(xiàn)超時(shí)錯(cuò)誤浆劲,這樣,發(fā)送端就了解到了通信雙方的線路承載能力礁扮,也就確定了擁塞窗口的大小呀伙,發(fā)送方就用這個(gè)擁塞窗口的大小發(fā)送數(shù)據(jù)补履。要觀察這個(gè)現(xiàn)象是非常容易的,我們一般在下載數(shù)據(jù)的時(shí)候剿另,速度都是慢慢“沖起來的”
以上就是TCP數(shù)據(jù)傳輸?shù)拇笾铝鞒腆锎福m然并不細(xì)致,但是足以描述TCP的工作原理雨女,重點(diǎn)是TCP的流量控制原理谚攒,滑動(dòng)窗口,擁塞窗口氛堕,ACK累計(jì)確認(rèn)等知識(shí)點(diǎn)馏臭。
TCP的超時(shí)與重傳
超時(shí)重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的另一個(gè)重要機(jī)制,其原理是在發(fā)送某一個(gè)數(shù)據(jù)以后就開啟一個(gè)計(jì)時(shí)器讼稚,在一定時(shí)間內(nèi)如果沒有得到發(fā)送的數(shù)據(jù)報(bào)的ACK報(bào)文括儒,那么就重新發(fā)送數(shù)據(jù),直到發(fā)送成功為止锐想。
1.超時(shí)
超時(shí)時(shí)間的計(jì)算是超時(shí)的核心部分帮寻,TCP要求這個(gè)算法能大致估計(jì)出當(dāng)前的網(wǎng)絡(luò)狀況,雖然這確實(shí)很困難赠摇。要求精確的原因有兩個(gè):
- (1)定時(shí)長(zhǎng)久會(huì)造成網(wǎng)絡(luò)利用率不高固逗。
- (2)定時(shí)太短會(huì)造成多次重傳浅蚪,使得網(wǎng)絡(luò)阻塞。所以烫罩,書中給出了一套經(jīng)驗(yàn)公式惜傲,和其他的保證計(jì)時(shí)器準(zhǔn)確的措施。
1.1.遞推公式概說
最早的TCP曾經(jīng)用了一個(gè)非常簡(jiǎn)單的公式來估計(jì)當(dāng)前網(wǎng)絡(luò)的狀況贝攒,如下
R<-aR+(1-a)M
RTP=Rb
其中a是一個(gè)經(jīng)驗(yàn)系數(shù)為0.1盗誊,b通常為2。注意饿这,這是經(jīng)驗(yàn)浊伙,沒有推導(dǎo)過程撞秋,這個(gè)數(shù)值是可以被修改的长捧。這個(gè)公式是說用舊的RTT(R)和新的RTT(M)綜合到一起來考慮新的RTT(R)的大小。但是吻贿,我們又看到串结,這種估計(jì)在網(wǎng)絡(luò)變化很大的情況下完全不能做出“靈敏的反應(yīng)”(Jacoboson說的,不是偶說的舅列,呵呵)肌割,于是就有下面的修正公式:
Err=M-A
A<-A+gErr
D<-D+h(|Err|-D)
RTO=A+4D
具體的解釋請(qǐng)看書的228頁,這個(gè)遞推公式甚至把方差這種統(tǒng)計(jì)概念也使用了進(jìn)來帐要,使得偏差更加的小把敞。而且,必須要指出的是榨惠,這兩組公式更新奋早,都是在數(shù)據(jù)成功傳輸?shù)那闆r下才進(jìn)行,在發(fā)生數(shù)據(jù)重新傳輸?shù)那闆r下赠橙,并不使用上面的公式進(jìn)行網(wǎng)絡(luò)估計(jì)耽装,理由很簡(jiǎn)單,因?yàn)槌绦蛞呀?jīng)不在正常狀態(tài)下了期揪,估計(jì)出來的數(shù)據(jù)也是沒有意義的掉奄。
1.2.RTO的初始化
RTO的初始化是由公式?jīng)Q定的,例如最初的公式凤薛,初始的值應(yīng)該是1姓建。而修正公式,初始RTO應(yīng)該是A+4D缤苫。
1.3.RTO的更新
當(dāng)數(shù)據(jù)正常傳輸?shù)那闆r下引瀑,我們就會(huì)用上面的公式來更新各個(gè)數(shù)據(jù),并重開定時(shí)器榨馁,來保證下一個(gè)數(shù)據(jù)被順利傳輸憨栽。要注意的是:重傳的情況下,RTO不用上面的公式計(jì)算,而采用一種叫做“指數(shù)退避”的方式屑柔。例如:當(dāng)RTO為1S的情況下屡萤,發(fā)生了數(shù)據(jù)重傳,我們就用RTO=2S的定時(shí)器來重新傳輸數(shù)據(jù)掸宛,下一次用4S死陆。一直增加到64S為止。
1.4.估計(jì)器的初始化
在這里唧瘾,SYN用的估計(jì)器初始化似乎和傳輸用的估計(jì)器不一樣(我也沒有把握)造我的理解措译,在修正公式中,SYN的情況下饰序,A初始化為0,D初始化為3S领虹。
而在得到傳輸?shù)谝粋€(gè)數(shù)據(jù)的ACK的時(shí)候,應(yīng)該按照下面的公式進(jìn)行初始化:
A=M+0.5
D=A/2
1.5.估計(jì)器的更新
和上面的討論差不多求豫,就是在正常情況下塌衰,用上面的公式計(jì)算,在重傳的情況下蝠嘉,不更新估計(jì)器的各種參數(shù)最疆。原因還是因?yàn)楣烙?jì)不準(zhǔn)確。
1.6.Karn算法
這不算是一個(gè)算法蚤告,這應(yīng)該是一個(gè)策略努酸,說的就是更新RTO和估計(jì)器的值的時(shí)機(jī)選擇問題,1.3.和1.5.所說得更新時(shí)機(jī)就是Karn算法杜恰。
1.7.計(jì)時(shí)器的使用
兩句話:一個(gè)連接中获诈,有且僅有一個(gè)測(cè)量定時(shí)器被使用。也就是說箫章,如果TCP連續(xù)發(fā)出3組數(shù)據(jù)烙荷,只有一組數(shù)據(jù)會(huì)被測(cè)量。
ACK數(shù)據(jù)報(bào)不會(huì)被測(cè)量檬寂,原因很簡(jiǎn)單终抽,沒有ACK的ACK回應(yīng)可以供結(jié)束定時(shí)器測(cè)量。
2.重傳
有了超時(shí)就要有重傳桶至,但是就算是重傳也是有策略的昼伴,而不是將數(shù)據(jù)簡(jiǎn)單的發(fā)送。
2.1.重傳時(shí)發(fā)送數(shù)據(jù)的大小
前面曾經(jīng)提到過镣屹,數(shù)據(jù)在傳輸?shù)臅r(shí)候不能只使用一個(gè)窗口協(xié)議圃郊,我們還需要有一個(gè)擁塞窗口來控制數(shù)據(jù)的流量,使得數(shù)據(jù)不會(huì)一下子都跑到網(wǎng)路中引起“擁塞”女蜈。也曾經(jīng)提到過持舆,擁塞窗口最初使用指數(shù)增長(zhǎng)的速度來增加自身的窗口色瘩,直到發(fā)生超時(shí)重傳,再進(jìn)行一次微調(diào)逸寓。但是沒有提到居兆,如何進(jìn)行微調(diào),擁塞避免算法和慢啟動(dòng)門限就是為此而生竹伸。
所謂的慢啟動(dòng)門限就是說泥栖,當(dāng)擁塞窗口超過這個(gè)門限的時(shí)候,就使用擁塞避免算法勋篓,而在門限以內(nèi)就采用慢啟動(dòng)算法吧享。所以這個(gè)標(biāo)準(zhǔn)才叫做門限,通常譬嚣,擁塞窗口記做cwnd钢颂,慢啟動(dòng)門限記做ssthresh。下面我們來看看擁塞避免和慢啟動(dòng)是怎么一起工作的
算法概要(直接從書中拷貝)
對(duì)一個(gè)給定的連接孤荣,初始化cwnd為1個(gè)報(bào)文段甸陌,ssthresh為65535個(gè)字節(jié)须揣。
TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小盐股。擁塞避免是發(fā)送方使用 的流量控制,而通告窗口則是接收方進(jìn)行的流量控制耻卡。前者是發(fā)送方感受到的網(wǎng)絡(luò)擁塞的估 計(jì)疯汁,而后者則與接收方在該連接上的可用緩存大小有關(guān)。
當(dāng)擁塞發(fā)生時(shí)(超時(shí)或收到重復(fù)確認(rèn))卵酪,ssthresh被設(shè)置為當(dāng)前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值幌蚊,但最少為2個(gè)報(bào)文段)。此外溃卡,如果是超時(shí)引起了擁塞溢豆,則 cwnd被設(shè)置為1個(gè)報(bào)文段(這就是慢啟動(dòng))。
當(dāng)新的數(shù)據(jù)被對(duì)方確認(rèn)時(shí)瘸羡,就增加cwnd漩仙,但增加的方法依賴于我們是否正在進(jìn)行慢啟動(dòng)或擁塞避免。如果cwnd小于或等于ssthresh犹赖,則正在進(jìn)行慢啟動(dòng)队他,否則正在進(jìn)行擁塞避免。 慢啟動(dòng)一直持續(xù)到我們回到當(dāng)擁塞發(fā)生時(shí)所處位置的半時(shí)候才停止(因?yàn)槲覀冇涗浟嗽诓襟E2 中給我們制造麻煩的窗口大小的一半)峻村,然后轉(zhuǎn)為執(zhí)行擁塞避免麸折。
補(bǔ)充上面的擁塞避免公式在P238頁。
2.2.快速重傳和快速恢復(fù)算法
這是數(shù)據(jù)丟包的情況下給出的一種修補(bǔ)機(jī)制粘昨。一般來說垢啼,重傳發(fā)生在超時(shí)之后窜锯,但是如果發(fā)送端接受到3個(gè)以上的重復(fù)ACK的情況下,就應(yīng)該意識(shí)到芭析,數(shù)據(jù)丟了衬浑,需要重新傳遞。這個(gè)機(jī)制是不需要等到重傳定時(shí)器溢出的放刨,所以叫做快速重傳工秩,而重新傳遞以后,因?yàn)樽叩牟皇锹龁?dòng)而是擁塞避免算法进统,所以又稱為快速恢復(fù)算法助币。流程如下:
- 當(dāng)收到第3個(gè)重復(fù)的ACK時(shí),將ssthresh設(shè)置為當(dāng)前擁塞窗口cwnd的一半螟碎。重傳丟失的 報(bào)文段眉菱。設(shè)置cwnd為ssthresh加上3倍的報(bào)文段大小。
- 每次收到另一個(gè)重復(fù)的ACK時(shí)掉分, cwnd增加1個(gè)報(bào)文段大小并發(fā)送1個(gè)分組(如果新的 cwnd允許發(fā)送)俭缓。
- 當(dāng)下一個(gè)確認(rèn)新數(shù)據(jù)的ACK到達(dá)時(shí),設(shè)置cwnd為ssthresh(在第1步中設(shè)置的值)酥郭。這個(gè) ACK應(yīng)該是在進(jìn)行重傳后的一個(gè)往返時(shí)間內(nèi)對(duì)步驟1中重傳的確認(rèn)华坦。另外,這個(gè)ACK也應(yīng)該 是對(duì)丟失的分組和收到的第1個(gè)重復(fù)的ACK之間的所有中間報(bào)文段的確認(rèn)不从。這一步采用的是擁塞避免惜姐,因?yàn)楫?dāng)分組丟失時(shí)我們將當(dāng)前的速率減半。
2.3.ICMP會(huì)引起重新傳遞么椿息?
不會(huì)歹袁,TCP會(huì)堅(jiān)持用自己的定時(shí)器,但TCP會(huì)保留下ICMP的錯(cuò)誤并且通知用戶寝优。
2.4.重新分組
TCP為了提高自己的效率条舔,允許再重新傳輸?shù)臅r(shí)候,只要傳輸包含重傳數(shù)據(jù)報(bào)文的報(bào)文就可以乏矾,而不用只重傳需要傳輸?shù)膱?bào)文孟抗。
TCP堅(jiān)持定時(shí)器,TCP逼扌埽活定時(shí)器
TCP一共有四個(gè)主要的定時(shí)器夸浅,前面已經(jīng)講到了一個(gè)--超時(shí)定時(shí)器--是TCP里面最復(fù)雜的一個(gè),另外的三個(gè)是:
堅(jiān)持定時(shí)器
比右郏活定時(shí)器
2MSL定時(shí)器
其中堅(jiān)持定時(shí)器用于防止通告窗口為0以后帆喇,雙方互相等待死鎖的情況;而币谛兀活定時(shí)器則用于處理半開放連接坯钦。
1.堅(jiān)持定時(shí)器
堅(jiān)持定時(shí)器的原理是簡(jiǎn)單的预皇,當(dāng)TCP服務(wù)器收到了客戶端的0滑動(dòng)窗口報(bào)文的時(shí)候,就啟動(dòng)一個(gè)定時(shí)器來計(jì)時(shí)婉刀,并在定時(shí)器溢出的時(shí)候向向客戶端查詢窗口是否已經(jīng)增大吟温,如果得到非零的窗口就重新開始發(fā)送數(shù)據(jù),如果得到0窗口就再開一個(gè)新的定時(shí)器準(zhǔn)備下一次查詢突颊。通過觀察可以得知鲁豪,TCP的堅(jiān)持定時(shí)器使用1,2律秃,4爬橡,8,16……64秒這樣的普通指數(shù)退避序列來作為每一次的溢出時(shí)間棒动。
糊涂窗口綜合癥
TCP的窗口協(xié)議糙申,會(huì)引起一種通常叫做糊涂窗口綜合癥的問題,具體表現(xiàn)為船惨,當(dāng)客戶端通告一個(gè)小的非零窗口時(shí)柜裸,服務(wù)器立刻發(fā)送小數(shù)據(jù)給客戶端并充滿其緩沖區(qū),一來二去就會(huì)讓網(wǎng)絡(luò)中充滿小TCP數(shù)據(jù)報(bào)粱锐,從而影響網(wǎng)絡(luò)利用率疙挺。對(duì)于發(fā)送方和接收端的這種糊涂行為。TCP給出了一些建議(或者是規(guī)定)卜范。
接收方不通告小窗口衔统。
通常的算法是接收方不通告一個(gè)比當(dāng)前窗口大的窗口(可以為0)鹿榜,除非窗口可以增加一個(gè)報(bào)文段大泻Q(也就是將要接收的MSS)或者可以增加接收方緩存空間的一半,不論實(shí)際有多少舱殿。
發(fā)送方避免出現(xiàn)糊涂窗口綜合癥的措施是只有以下條件之一滿足時(shí)才發(fā)送數(shù)據(jù):
- 可以發(fā)送一個(gè)滿長(zhǎng)度的報(bào)文段奥裸;
- 可以發(fā)送至少是接收方通告窗口大小一半的報(bào)文段;
- 可以發(fā)送任何數(shù)據(jù)并且不希望接收ACK(也就是說沪袭,我們沒有還未被確認(rèn)的數(shù)據(jù))或者該連接上不能使用Nagle算法湾宙。
ok,現(xiàn)在我們回憶一下冈绊,可以發(fā)現(xiàn)TCP的很多規(guī)定都是為了在一次傳送中發(fā)送盡量多的數(shù)據(jù)侠鳄,例如捎帶ACK數(shù)據(jù)報(bào)文的策略,Nagle算法死宣,重傳時(shí)發(fā)送包含原數(shù)據(jù)報(bào)文的策略融撞,等等草穆。
2.保活定時(shí)器
比荩活定時(shí)器更加的簡(jiǎn)單,還記得FTP或者Http服務(wù)器都有Sesstion Time機(jī)制么泛领?因?yàn)?strong>TCP是面向連接的,所以就會(huì)出現(xiàn)只連接不傳送數(shù)據(jù)的“半開放連接”,服務(wù)器當(dāng)然要檢測(cè)到這種連接并且在某些情況下釋放這種連接巴碗,這就是保活定時(shí)器的作用即寒。其時(shí)限根據(jù)服務(wù)器的實(shí)現(xiàn)不同而不通橡淆。另外要提到的是,當(dāng)其中一端如果崩潰并重新啟動(dòng)的情況下母赵,如果收到該端“前生”的泵鞴福活探察,則要發(fā)送一個(gè)RST數(shù)據(jù)報(bào)文幫助另一端結(jié)束連接市咽。
在TCP剛出世的時(shí)候痊银,其主要工作環(huán)境是以太網(wǎng)和SLIP之類的低速網(wǎng)絡(luò)。隨著高速網(wǎng)絡(luò)的出現(xiàn)施绎,讓TCP協(xié)議的吞吐量更大溯革,效率更高的要求就愈來愈迫切。為此谷醉,TCP增加了三個(gè)重要機(jī)制來對(duì)應(yīng)現(xiàn)在的變化致稀,他們是
- 路徑MTU發(fā)現(xiàn)。
- 窗口擴(kuò)大選項(xiàng)和時(shí)間戳俱尼。
- T/TCP(增加了事務(wù)功能的TCP協(xié)議)抖单。
1.路徑MTU發(fā)現(xiàn)
顧名思義路徑MTU指的是源主機(jī)到墓地主機(jī)之間的路徑的可傳送最大單元的大小。其原理同樣是使用設(shè)置了不許分片的IP數(shù)據(jù)報(bào)遇八,并等待ICMP錯(cuò)誤矛绘,來估算MTU的大小。書中的P257介紹了TCP如何根據(jù)ICMP的報(bào)文來修改自己的MTU刃永。具體如下:
- 當(dāng)源主機(jī)接收到較新的ICMP差錯(cuò)報(bào)文時(shí)货矮,就直接修改自己的最大發(fā)送報(bào)文段大小為發(fā)送ICMP差錯(cuò)報(bào)文的發(fā)送端的MTU與IP頭和TCP頭的差值。
- 當(dāng)源主機(jī)接收到較新的ICMP差錯(cuò)報(bào)文時(shí)斯够,則必須嘗試下一個(gè)MTU(各種不同的網(wǎng)絡(luò)設(shè)備都有一個(gè)MTU囚玫,各個(gè)MTU從大到小為"65535,17914,4464,4352,1500,1492,576,296")。
- 因?yàn)槁酚煽梢詣?dòng)態(tài)變化读规,所以每隔10分鐘抓督,發(fā)送端就可以用比較大的報(bào)文來偵測(cè)一下路徑MTU。
2.長(zhǎng)肥管道
所謂的長(zhǎng)肥管道束亏,說的就是發(fā)送時(shí)延長(zhǎng)铃在,帶寬寬的管道,衡量這一概念的標(biāo)準(zhǔn)是時(shí)延面積枪汪。如果碰上了網(wǎng)絡(luò)“又長(zhǎng)又肥”涌穆,那么網(wǎng)絡(luò)的利用率就會(huì)大幅度的降低怔昨,普通的計(jì)時(shí)方法和窗口面積就不夠用了。就需要更多的措施來彌補(bǔ)這個(gè)缺陷宿稀。這就是時(shí)間戳和窗口擴(kuò)大選項(xiàng)趁舀。這些都是在經(jīng)典TCP協(xié)議頭之外定義的擴(kuò)展選項(xiàng),格式如下:
2.1.時(shí)間戳選項(xiàng)
用戶在發(fā)送每一個(gè)TCP報(bào)文的時(shí)候都放置一個(gè)時(shí)間戳祝沸,接受方在確認(rèn)中返回這個(gè)時(shí)間戳值矮烹。發(fā)送方就可以根據(jù)這個(gè)時(shí)間戳來計(jì)算RTT。從而使得RTT更加精確罩锐,減少不必要的重傳奉狈。減低網(wǎng)絡(luò)的負(fù)載。
2.2.窗口擴(kuò)大選項(xiàng)
很奇怪的是為什么窗口最大的擴(kuò)展量只有14而不是64涩惑。因?yàn)楫吘勾翱跀U(kuò)大選項(xiàng)有一個(gè)字節(jié)那么長(zhǎng)的數(shù)據(jù)可以用仁期,不過,不管怎么樣竭恬,還是記住為好跛蛋。窗口擴(kuò)大選項(xiàng)可以讓窗口擴(kuò)大到2的30次方。這就幾乎完美的解決了肥管道的問題痊硕。