TCP/IP協(xié)議

<pre>

個人認為外邓,Goodboy1881先生的TCP /IP 協(xié)議詳解學習博客系列博客是一部非常精彩的學習筆記漏健,這雖然只是他個人的筆記非凌,但是這個系列的博客對我們這些讀者具有非常大的啟迪作用金抡。

我想瀑焦,這一系列的博客對于我們這些讀者更大的意義在于:這可以當作我們去閱讀、學習《TCP/IP協(xié)議詳解》這一本經典的提綱吧梗肝!


首先榛瓮,TCP/IP不是一個協(xié)議,而是一個協(xié)議族的統(tǒng)稱巫击。

里面包括了IP協(xié)議禀晓,IMCP協(xié)議TCP協(xié)議喘鸟,以及http匆绣、ftppop3協(xié)議等等什黑。

TCP/IP協(xié)議分層

提到協(xié)議分層崎淳,我們很容易聯(lián)想到ISO-OSI的七層協(xié)議經典架構,但是TCP/IP協(xié)議族的結構則稍有不同愕把。如圖所示

[圖片上傳失敗...(image-a7cf0c-1511441165324)]

TCP/IP協(xié)議族按照層次由上到下拣凹,層層包裝森爽。

第一層就是應用層,這里面有http嚣镜,ftp,等等我們熟悉的協(xié)議爬迟。
第二層是傳輸層,著名的TCPUDP協(xié)議就在這個層次菊匿。
第三層是網絡層付呕,IP協(xié)議就在這里藻雪,它負責對數(shù)據(jù)加上IP地址和其他的數(shù)據(jù)以確定傳輸?shù)哪繕恕?br> 第四層是數(shù)據(jù)鏈路層证杭,這個層次為待傳送的數(shù)據(jù)加入一個以太網協(xié)議頭,并進行CRC編碼偷卧,為最后的數(shù)據(jù)傳輸做準備佩厚。
再往下則是硬件層次姆钉,負責網絡的傳輸,這個層次的定義包括網線的制式抄瓦,網卡的定義等等潮瓶,故有些書并不將這個層次放在TCP/IP協(xié)議族里面,因為它幾乎和TCP/IP協(xié)議的編寫者沒有任何的關系钙姊。發(fā)送協(xié)議的主機從上自下將數(shù)據(jù)按照協(xié)議封裝毯辅,而接收數(shù)據(jù)的主機則按照協(xié)議從得到的數(shù)據(jù)包解開,最后拿到需要的數(shù)據(jù)摸恍。這種結構非常有棧的味道悉罕,故某些文章亦將TCP/IP協(xié)議族稱為TCP/IP協(xié)議棧。


一些基本的常識

在學習協(xié)議之前立镶,我們應該具備一些如下的基本知識壁袄。

互聯(lián)網地址(IP地址)

網絡上每一個節(jié)點都必須有一個獨立的Internet地址(也叫做IP地址)。
現(xiàn)在媚媒,通常使用的IP地址是一個32bit的數(shù)字嗜逻,也就是我們常說的IPv4標準,這32bit的數(shù)字分成四組缭召,也就是常見的255.255.255.255的樣式栈顷。
IPv4標準上,地址被分為五類嵌巷,我們常用的是B類地址萄凤。具體的分類請參考其他文檔。需要注意的是IP地址是網絡號+主機號的組合搪哪。

域名系統(tǒng)

域名系統(tǒng)是一個分布的數(shù)據(jù)庫靡努,它提供將主機名(即網址)轉換成IP地址的服務。

RFC

RFC是什么?RFC就是tcp/ip協(xié)議的標準文檔惑朦,在這里我們可以看到RFC那長長的定義列表兽泄,現(xiàn)在它一共有4000多個協(xié)議的定義,當然漾月,我們所要學習的病梢,也就是那么十幾個協(xié)議而已。

端口號(port)

注意梁肿,這個號碼是用在TCP蜓陌,UDP上的一個邏輯號碼,并不是一個硬件端口吩蔑,我們平時說把某某端口封掉了护奈,也只是在IP層次把帶有這個號碼的IP包給過濾掉了而已。

應用編程接口

現(xiàn)在常用的編程接口有socketTLI哥纫。


數(shù)據(jù)鏈路層

數(shù)據(jù)鏈路層有三個目的:

  • 為IP模塊發(fā)送和接收IP數(shù)據(jù)報。

  • 為ARP模塊發(fā)送ARP請求和接收ARP應答痴奏。

  • 為RARP發(fā)送RARP請 求和接收RARP應答蛀骇。

IP大家都聽說過。至于ARP和RARP读拆,ARP叫做地址解析協(xié)議擅憔,是用IP地址換MAC地址的一種協(xié)議,而RARP叫做逆地址解析協(xié)議(在局域網中用ARP協(xié)議可以很容易使網絡癱瘓)檐晕。

數(shù)據(jù)鏈路層的協(xié)議還是很多的暑诸,有我們最常用的以太網協(xié)議,也有不太常見的令牌環(huán)辟灰,還有FDDI个榕,當然,還有國內現(xiàn)在相當普及的PPP協(xié)議(就是adsl寬帶)芥喇,以及一個loopback協(xié)議西采。

聯(lián)系linux里面的ifconfig -a命令,這個命令通常會得到如下的結果:

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就是以太網接口械馆,而lo則是loopback接口。這也說明這個主機在網絡鏈路層上至少支持loopback協(xié)議和以太網協(xié)議武通。

以太網(Ether-net)的定是指數(shù)字設備公司( Digital Equipment Corp.)霹崎、英特爾公司(Intel Corp.)和Xerox公司在1982年聯(lián)合公布的一個標準,這個標準里面使用了一種稱作CSMA/CD的接入方法冶忱。而IEEE802提供的標準集802.3(還有一部分定義到了802.2中)也提供了一個CSMA/CD的標準尾菇。

這兩個標準稍有不同,TCP/IP協(xié)議對這種情況的處理方式如下:

以太網的IP數(shù)據(jù)報封裝在RFC894中定義,而IEEE802網絡的IP數(shù)據(jù)報封裝在RFC1042中定義错沽。

  • 一臺主機一定要能發(fā)送和接收RFC894定義的數(shù)據(jù)報簿晓。
  • 一臺主機可以接收RFC894和RFC1042的封裝格式的混合數(shù)據(jù)報

  • 一臺主機也許能夠發(fā)送RFC1042數(shù)據(jù)報千埃。

如果主機能同時發(fā)送兩種類型的分組數(shù)據(jù)憔儿,那么發(fā)送的分組必須是可以設置的,而且默認條件下必須是RFC 894分組放可。

可見谒臼,RFC1042在TCP/IP里面處于一個配角的地位。這兩種不同的數(shù)據(jù)報格式請參考教材耀里。

ppp(點對點協(xié)議)是從SLIP的替代品蜈缤。
他們都提供了一種低速接入的解決方案。而每一種數(shù)據(jù)鏈路層協(xié)議冯挎,都有一個MTU(最大傳輸單元)定義底哥,在這個定義下面,如果IP數(shù)據(jù)報過大房官,則要進行分片(fragmentation)趾徽,使得每片都小于MTU,注意PPP的MTU并不是一個物理定義翰守,而是指一個邏輯定義(個人認為就是用程序控制)孵奶。

可以用netstat來打印出MTU的結果,比如鍵入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了袁。
最后說說那個環(huán)回接口(loopback)。平時我們用127.0.0.1來嘗試自己的機器服務器好使不好使湿颅。走的就是這個loopback接口载绿。

對于環(huán)回接口,有如下三點值得注意:
  • 傳給環(huán)回地址(一般是127.0.0.1)的任何數(shù)據(jù)均作為IP輸入肖爵。

  • 傳給廣播地址或多播地址的數(shù)據(jù)報復制一份傳給環(huán)回接口卢鹦,然后送到以太網上。這是因為廣播傳送和多播傳送的定義包含主機本身劝堪。

  • 任何傳給該主機IP地址的數(shù)據(jù)均送到環(huán)回接口冀自。

IP協(xié)議,ARP協(xié)議, RARP 協(xié)議

把這三個協(xié)議放到一起學習是因為這三個協(xié)議處于同一層,ARP協(xié)議用來找到目標主機的Ethernet網卡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ù)未傳達以后的處理機制--這被認為是上層協(xié)議--TCP或UDP要做的事情。因而出現(xiàn)了TCP是一個可靠的協(xié)議肥惭,而UDP就沒有那么可靠的區(qū)別盯仪。

1.1.IP協(xié)議頭

如圖所示

[圖片上傳失敗...(image-5bc422-1511441165316)]

挨個解釋它是教科書的活計,我感興趣的只是那八位的TTL字段蜜葱,還記得這個字段是做什么的么全景?

這個字段規(guī)定該數(shù)據(jù)包在穿過多少個路由之后才會被拋棄(這里就體現(xiàn)出來IP協(xié)議包的不可靠性,它不保證數(shù)據(jù)被送達)牵囤,某個ip數(shù)據(jù)包每穿過一個路由器爸黄,該數(shù)據(jù)包的TTL數(shù)值就會減少1當該數(shù)據(jù)包的TTL成為零揭鳞,它就會被自動拋棄馆纳。這個字段的最大值也就是255,也就是說一個協(xié)議包也就在路由器里面穿行255次就會被拋棄了汹桦,根據(jù)系統(tǒng)的不同,這個數(shù)字也不一樣鉴裹,一般是32或者是64舞骆。

Tracerouter這個工具就是用這個原理工作的,tranceroute的-m選項要求最大值是255径荔,也就是因為這個TTL在IP協(xié)議里面只有8bit督禽。

現(xiàn)在的IP版本號是4,所以也稱作IPv4∽艽Γ現(xiàn)在還有IPv6狈惫,而且運用也越來越廣泛了。

1.2.IP路由選擇

當一個IP數(shù)據(jù)包準備好了的時候鹦马,IP數(shù)據(jù)包(或者說是路由器)是如何將數(shù)據(jù)包送到目的地的呢胧谈?它是怎么選擇一個合適的路徑來"送貨"的呢?

  1. 最特殊的情況是目的主機和主機直連荸频,那么主機根本不用尋找路由菱肖,可以直接把數(shù)據(jù)傳遞過去。至于是怎么直接傳遞的旭从,這就要靠ARP協(xié)議了稳强,后面會講到场仲。
  1. 稍微一般一點的情況是,主機通過若干個路由器(router)和目的主機連接退疫。那么路由器就要通過ip包的信息來為ip包尋找到一個合適的目標來進行傳遞渠缕,比如合適的主機,或者合適的路由褒繁。路由器或者主機將會用如下的方式來處理某一個IP數(shù)據(jù)包:
  • 如果IP數(shù)據(jù)包的TTL(生命周期)已到亦鳞,則該IP數(shù)據(jù)包就被拋棄。

  • 搜索路由表澜汤,優(yōu)先搜索匹配主機蚜迅,如果能找到和IP地址完全一致的目標主機,則將該包發(fā)向目標主機俊抵。

  • 搜索路由表谁不,如果匹配主機失敗,則匹配同子網的路由器徽诲,這需要“子網掩碼(1.3.)”的協(xié)助刹帕。如果找到路由器,則將該包發(fā)向路由器谎替。

  • 搜索路由表偷溺,如果匹配同子網路由器失敗,則匹配同網號路由器钱贯,如果找到路由器挫掏,則將該包發(fā)向路由器。

  • 搜索路由表秩命,如果以上都失敗了尉共,就搜索默認路由,如果默認路由存在弃锐,則發(fā)包袄友。

  • 如果都失敗了,就丟掉這個包霹菊。

這再一次證明了剧蚣,IP包是不可靠的。因為它不保證送達旋廷。

1.3.子網尋址

IP地址的定義是網絡號+主機號鸠按。

但是現(xiàn)在所有的主機都要求子網編址,也就是說饶碘,把主機號在細分成子網號+主機號待诅。最終一個IP地址就成為網絡號碼+子網號+主機號。例如一個B類地址:210.30.109.134熊镣。一般情況下卑雁,這個IP地址的紅色部分就是網絡號募书,而藍色部分就是子網號,綠色部分就是主機號测蹲。至于有多少位代表子網號這個問題上莹捡,這沒有一個硬性的規(guī)定,取而代之的則是子網掩碼扣甲,校園網相信大多數(shù)人都用過篮赢,在校園網的設定里面有一個255.255.255.0的東西,這就是子網掩碼琉挖。

子網掩碼是由32bit的二進制數(shù)字序列,形式為是一連串的1和一連串的0启泣。

例如:

255.255.255.0(二進制就是11111111.11111111.11111111.00000000)對于剛才的那個B類地址,因為210.30是網絡號示辈,那么后面的109.134就是子網號和主機號的組合寥茫,又因為子網掩碼只有后八bit為0,所以主機號就是IP地址的后八個bit矾麻,就是134纱耻,而剩下的就是子網號碼--109。

2. ARP協(xié)議

還記得數(shù)據(jù)鏈路層的以太網的協(xié)議中险耀,每一個數(shù)據(jù)包都有一個MAC地址頭么弄喘?我們知道每一塊以太網卡都有一個MAC地址,這個地址是唯一的甩牺,那么IP包是如何知道這個MAC地址的蘑志?這就是ARP協(xié)議的工作。

ARP(地址解析)協(xié)議是一種解析協(xié)議贬派,本來主機是完全不知道這個IP對應的是哪個主機的哪個接口卖漫,當主機要發(fā)送一個IP包的時候,會首先查一下自己的ARP高速緩存(就是一個IP-MAC地址對應表緩存)赠群,如果查詢的IP-MAC值對不存在,那么主機就向網絡發(fā)送一個ARP協(xié)議廣播包旱幼,這個廣播包里面就有待查詢的IP地址查描,而直接收到這份廣播的包的所有主機都會查詢自己的IP地址,如果收到廣播包的某一個主機發(fā)現(xiàn)自己符合條件柏卤,那么就準備好一個包含自己的MAC地址的ARP包傳送給發(fā)送ARP廣播的主機冬三,而廣播主機拿到ARP包后會更新自己的ARP緩存(就是存放IP-MAC對應表的地方)。發(fā)送廣播的主機就會用新的ARP緩存數(shù)據(jù)準備好數(shù)據(jù)鏈路層的的數(shù)據(jù)包發(fā)送工作缘缚。

一個典型的arp緩存信息如下勾笆,在任意一個系統(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

都會得到這樣的結果。
這樣的高速緩存是有時限的桥滨,一般是20分鐘(伯克利系統(tǒng)的衍生系統(tǒng))窝爪。

3.RARP協(xié)議(略)


ICMP協(xié)議弛车,ping和Traceroute

1.IMCP協(xié)議介紹

前面講到了,IP協(xié)議并不是一個可靠的協(xié)議蒲每,它不保證數(shù)據(jù)被送達纷跛,那么,自然的邀杏,保證數(shù)據(jù)送達的工作應該由其他的模塊來完成贫奠。其中一個重要的模塊就是ICMP(網絡控制報文)協(xié)議。

當傳送IP數(shù)據(jù)包發(fā)生錯誤——比如主機不可達望蜡,路由不可達等等唤崭,ICMP協(xié)議將會把錯誤信息封包,然后傳送回給主機脖律。給主機一個處理錯誤的機會谢肾,這也就是為什么說建立在IP層以上的協(xié)議是可能做到安全的原因。ICMP數(shù)據(jù)包由8bit的錯誤類型和8bit的代碼和16bit的校驗和組成状您。而前16bit就組成了ICMP所要傳遞的信息勒叠。

書上的圖6-3清楚的給出了錯誤類型和代碼的組合代表的意思。

盡管在大多數(shù)情況下膏孟,錯誤的包傳送應該給出ICMP報文眯分,但是在特殊情況下,是不產生ICMP錯誤報文的柒桑。如下:

  • ICMP差錯報文不會產生ICMP差錯報文(出IMCP查詢報文)(防止IMCP的無限產生和傳送)

  • 目的地址是廣播地址或多播地址的IP數(shù)據(jù)報弊决。

  • 作為鏈路層廣播的數(shù)據(jù)報。

  • 不是IP分片的第一片魁淳。

  • 源地址不是單個主機的數(shù)據(jù)報飘诗。這就是說,源地址不能為零地址界逛、環(huán)回地址昆稿、廣播地 址或多播地址。

雖然里面的一些規(guī)定現(xiàn)在還不是很明白息拜,但是所有的這一切規(guī)定溉潭,都是為了防止產生ICMP報文的無限傳播而定義的

ICMP協(xié)議大致分為兩類少欺,一種是查詢報文喳瓣,一種是差錯報文。其中查詢報文有以下幾種用途:

  • ping查詢

  • 子網掩碼查詢(用于無盤工作站在初始化自身的時候初始化子網掩碼)

  • 時間戳查詢(同步時間)

差錯報文則產生在數(shù)據(jù)傳送發(fā)生錯誤的時候赞别。就不贅述了畏陕。

2.ICMP的應用--ping

ping可以說是ICMP的最著名的應用,當我們某一個網站上不去的時候仿滔。通常會ping一下這個網站惠毁。ping會回顯出一些有用的信息犹芹。一般的信息如下:

  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這個單詞源自聲納定位,而這個程序的作用也確實如此仁讨,它利用ICMP協(xié)議包來偵測另一個主機是否可達羽莺。原理是用類型碼為0的ICMP發(fā)請求,受到請求的主機則用類型碼為8的ICMP回應洞豁。ping程序來計算間隔時間盐固,并計算有多少個包被送達。用戶就可以判斷網絡大致的情況丈挟。我們可以看到刁卜,ping給出來了傳送的時間和TTL的數(shù)據(jù)。我給的例子不太好曙咽,因為走的路由少蛔趴,有興趣地可以ping一下國外的網站比如sf.net颁井,就可以觀察到一些丟包的現(xiàn)象谢揪,而程序運行的時間也會更加的長。
ping還給我們一個看主機到目的主機的路由的機會著恩。這是因為洒嗤,ICMP的ping請求數(shù)據(jù)報在每經過一個路由器的時候箫荡,路由器都會把自己的ip放到該數(shù)據(jù)報中。而目的主機則會把這個ip列表復制到回應icmp數(shù)據(jù)包中發(fā)回給主機渔隶。但是羔挡,無論如何,ip頭所能紀錄的路由列表是非常的有限间唉。如果要觀察路由绞灼, 我們還是需要使用更好的工具,就是要講到的Traceroute(windows下面的名字叫做tracert)呈野。

3.ICMP的應用--Traceroute

Traceroute是用來偵測主機到目的主機之間所經路由情況的重要工具低矮,也是最便利的工具。前面說到被冒,盡管ping工具也可以進行偵測军掂,但是,因為ip頭的限制姆打,ping不能完全的記錄下所經過的路由器。而Traceroute正好填補了這個缺憾肠虽。
Traceroute的原理是非常非常的有意思幔戏,它受到目的主機的IP后,首先給目的主機發(fā)送一個TTL=1的UDP數(shù)據(jù)包税课,而經過的第一個路由器收到這個數(shù)據(jù)包以后闲延,就自動把TTL減1痊剖,而TTL變?yōu)?以后,路由器就把這個包給拋棄了垒玲,并同時產生 一個主機不可達的ICMP數(shù)據(jù)報給主機陆馁。主機收到這個數(shù)據(jù)報以后再發(fā)一個TTL=2的UDP數(shù)據(jù)報給目的主機,然后刺激第二個路由器給主機發(fā)ICMP數(shù)據(jù) 報合愈。如此往復直到到達目的主機叮贩。這樣,traceroute就拿到了所有的路由器ip佛析。從而避開了ip頭只能記錄有限路由IP的問題益老。
那怎么知道UDP到沒到達目的主機呢?這就涉及一個技巧的問題寸莫,TCP和UDP協(xié)議有一個端口號定義捺萌,而普通的網絡程序只監(jiān)控少數(shù)的幾個號碼較 小的端口,比如說80,比如說23,等等膘茎。而traceroute發(fā)送的是端口號>30000(真變態(tài))的UDP報桃纯,所以到達目的主機的時候,目的 主機只能發(fā)送一個端口不可達的ICMP數(shù)據(jù)報給主機披坏。主機接到這個報告以后就知道态坦,主機到了,所以說Traceroute是個騙子一點也不為過:)
Traceroute程序里面提供了一些很有用的選項刮萌,甚至包含了IP選路的選項驮配,請察看man文檔來了解這些,不贅述着茸。


IP選路壮锻,動態(tài)選路,和一些細節(jié)

1.靜態(tài)IP選路

1.1.一個簡單的路由表

選路是IP層最重要的一個功能之一涮阔。前面的部分已經簡單的講過路由器是通過何種規(guī)則來根據(jù)IP數(shù)據(jù)包的IP地址來選擇路由猜绣。這里就不重復了。首先來看看一個簡單的系統(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

對于一個給定的路由器掰邢,可以打印出五種不同的flag。

  • U表明該路由可用伟阔。

  • G表明該路由是到一個網關辣之。如果沒有這個標志,說明和Destination是直連的皱炉,而相應的Gateway應該直接給出Destination的地址怀估。

  • H表明該路由是到一個主機,如果沒有該標志,說明Destination是一個網絡多搀,換句話說Destination就應該寫成一個網絡號和子網號的組合歧蕉,而不包括主機號(主機號碼處為0),例如 192.168.11.0

  • D表明該路由是為重定向報文創(chuàng)建的

  • M該路由已經被重定向報文修改

U沒啥可說的康铭,G說明這是一個網關惯退,如果你要發(fā)數(shù)據(jù)給Destination,IP頭應該寫Destination的IP地址从藤,而數(shù)據(jù)鏈路層的MAC地址就應該是GateWay的Mac地址了催跪;反之,如果沒有G標志呛哟,那么數(shù)據(jù)鏈路層和IP層的地址應該是對應的叠荠。H說明了Destination的性質,如果是H的扫责,則說明該地址是一個完整的地址榛鼎,既有網絡號又有主機號,那么再匹配的時候就既要匹配網絡號鳖孤,又要匹配主機號者娱;反之,Destination就代表一個網絡苏揣,在匹配的時候只要匹配一下網絡號就可以了黄鳍。
這樣,IP選路的方式就可以更加具體化了平匈。如下
首先用IP地址來匹配那些帶H標志的DestinationIP地址框沟。
如果1失敗就匹配那些網絡地址。
如果2失敗就發(fā)送到Default網關
順便提一下那個GenMask增炭,它指定了目的地址的子網號忍燥,例如第一條的子網就是11。

1.2.其他有關路由表的知識

一般隙姿,我們在配置好一個網絡接口的時候梅垄,一個路由就被直接創(chuàng)建好了。當然我們也可以手動添加路由输玷。用route add命令就可以了队丝。
而當一個IP包在某一個路由器的時候發(fā)現(xiàn)沒有路由可走,那么該路由器就會給源主機發(fā)送“主機不可達”或者“網絡不可達”的ICMP包來報錯欲鹏。
注意机久,一般的操作系統(tǒng)默認是沒有路由功能的,這需要自己配置赔嚎。這些歷史原因就不細說了膘盖,

1.3.ICMP的IP重定向報文和路由發(fā)現(xiàn)報文

當IP包在某一個地方轉向的時候,都回給發(fā)送IP報的源主機一個ICMP重定向報文,而源主機就可以利用這個信息來更新自己的路由表衔憨,這樣,隨著網絡通信的逐漸增多袄膏,路由表也就越來越完備践图,數(shù)據(jù)轉發(fā)的速度也會越來越快。我們需要注意的是:
重定向報文只能由路由器發(fā)出沉馆。
重定向報文為主機所用码党,而不是為路由器所用。
在主機引導的時候斥黑,一般會發(fā)送在網內廣播一個路由請求的ICMP報文揖盘,而多個路由器則會回應一個路由通告報文。而且锌奴,路由其本身不定期的在網絡內發(fā)布路由通告報文兽狭,這樣,根據(jù)這些報文鹿蜀,每一個主機都會有機會建立自己的路由表而實現(xiàn)網絡通信箕慧。路由器在一份通告報文中可以通告多個地址,并且給出每一個地址的優(yōu)先等級茴恰,這個優(yōu)先等級是該IP作為默認路由的等級颠焦,至于怎么算的就不深究了。
路由器一般會在450-600秒的時間間隔內發(fā)布一次通告往枣,而一個給定的通告報文的壽命是30分鐘伐庭。而主機在引導的時候會每三秒發(fā)送一次請求報文,一旦接受到一個有效的通告報文分冈,就停止發(fā)送請求報文圾另。
在TCP/IP詳解編寫的時候,只有Solaris2.x支持這兩種報文丈秩,大多數(shù)系統(tǒng)還不支持這兩種報文盯捌。(后面還會講到一些有用的路由報文)
動態(tài)選路協(xié)議
前面的選路方法叫做靜態(tài)選路,簡要地說就是在配置接口的時候蘑秽,以默認的方式生成路由表項饺著。并通過route來增加表項,或者通過ICMP報文來更新表項(通常在默認方式出錯的情況下)肠牲。 而如果上訴三種方法都不能滿足幼衰,那么我們就使用動態(tài)選路。
動態(tài)選路協(xié)議是用于動態(tài)選路的重要組成部分缀雳,但是他們只是使用在路由器之間渡嚣,相鄰路由器之間互相通信。系統(tǒng)(路由選擇程序)選擇比較合適的路有放到核心路由表中,然后系統(tǒng)就可以根據(jù)這個核心路有表找到最合適的網路识椰。也就是說绝葡,動態(tài)選路是在系統(tǒng)核心網絡外部進行的,它只是用一些選路的策略影響路由表腹鹉,而不會影響到最后通過路由表選擇路由的那一部分藏畅。選路協(xié)議有一大類常用的叫做內部網關協(xié)議(IGP),而在IGP中功咒,RIP就是其中最重要的協(xié)議愉阎。一種新的IGP協(xié)議叫做開放最短路經優(yōu)先(OSPF)協(xié)議,其意在取代RIP力奋。另一種最早用在網路骨干網上的IGP協(xié)議--HELLO榜旦,現(xiàn)在已經不用了。
如今景殷,任何支持動態(tài)選路的路由器都必須同時支持OSPF和RIP溅呢,還可以選擇性的支持其他的IGP協(xié)議。

2.1.Unix選路程序

Unix系統(tǒng)上面通常都有路由守護程序--routed猿挚。還有一個叫做gate藕届。gate所支持的協(xié)議要比routed多,routed只是支持RIPv1版本亭饵。而gate則支持RIPv1休偶、v2,BGPv1 等等辜羊。

2.1.RIP:選路信息協(xié)議

它的定義可以在RFC1058內找到踏兜,這種協(xié)議使用UDP作為載體(也就是UDP的上層協(xié)議)。我們最關心的就是RIP其中的一個段八秃,叫做度量的段碱妆,這是一個以hop作為計數(shù)器(就是以走過多少路由為計數(shù)器)的段(IP協(xié)議里面也有一個TTL)。這個度量段將最終影響到路由表的建立昔驱。參考圖:

[圖片上傳失敗...(image-64e5d0-1511441165315)]

一般說來routed要承擔如下的工作:
給每一個已知的路由器發(fā)送rip請求報文疹尾,要求其他路由器給出完整的路由表。這種報文的命令字段為1骤肛,地址字段為0纳本,度量地段為16(相當于無窮大)。
接受請求腋颠,如果接收到剛才的那個請求繁成,就把自己的完整的路由表交給請求者。如果沒有淑玫,就處理IP請求表項巾腕,把表項中自己有的部分添上跳數(shù)面睛,沒有的部分添上16。然后發(fā)給請求者尊搬。
接受回應叁鉴。更新自己的路由表。使用hop數(shù)小的規(guī)則佛寿。
定期更新路由表亲茅,一般是 30s 給相鄰的路由啟發(fā)一次自己的路由表。這種形式可以是廣播形式的狗准。
這個協(xié)議看起來會工作的很好,但是茵肃,這里面其實有很多隱藏的憂患腔长,比如說RIP沒有子網的概念,比如說環(huán)路的危險验残。而且hop數(shù)的上限也限制了網絡的大小捞附。
因此,出現(xiàn)了很多RIPv1的替代品您没,比如說RIPv2,比如說OSPF鸟召。他們都是通過某種策略來影響路由表,所以就不說了氨鹏。


UDP協(xié)議

1.UDP簡要介紹

UDP是傳輸層協(xié)議欧募,和TCP協(xié)議處于一個分層中,但是與TCP協(xié)議不同仆抵,UDP協(xié)議并不提供超時重傳跟继,出錯重傳等功能,也就是說其是不可靠的協(xié)議镣丑。

2.UDP協(xié)議頭

2.1.UDP端口號

由于很多軟件需要用到UDP協(xié)議舔糖,所以UDP協(xié)議必須通過某個標志用以區(qū)分不同的程序所需要的數(shù)據(jù)包。端口號的功能就在于此莺匠,例如某一個UDP程序A在系統(tǒng)中注冊了3000端口金吗,那么,以后從外面?zhèn)鬟M來的目的端口號為3000的UDP包都會交給該程序趣竣。端口號理論上可以有2^16這么多摇庙。因為它的長度是16個bit

2.2.UDP檢驗和

這是一個可選的選項,并不是所有的系統(tǒng)都對UDP數(shù)據(jù)包加以檢驗和數(shù)據(jù)(相對TCP協(xié)議的必須來說)遥缕,但是RFC中標準要求跟匆,發(fā)送端應該計算檢驗和。

UDP檢驗和覆蓋UDP協(xié)議頭和數(shù)據(jù)通砍,這和IP的檢驗和是不同的玛臂,IP協(xié)議的檢驗和只是覆蓋IP數(shù)據(jù)頭烤蜕,并不覆蓋所有的數(shù)據(jù)。UDP和TCP都包含一個偽首部迹冤,這是為了計算檢驗和而攝制的讽营。偽首部甚至還包含IP地址這樣的IP協(xié)議里面都有的信息,目的是讓UDP兩次檢查數(shù)據(jù)是否已經正確到達目的地泡徙。如果發(fā)送端沒有打開檢驗和選項橱鹏,而接收端計算檢驗和有差錯,那么UDP數(shù)據(jù)將會被悄悄的丟掉(不保證送達)堪藐,而不產生任何差錯報文莉兰。

2.3.UDP長度

UDP可以很長很長,可以有65535字節(jié)那么長礁竞。但是一般網絡在傳送的時候糖荒,一次一般傳送不了那么長的協(xié)議(涉及到MTU的問題),就只好對數(shù)據(jù)分片模捂,當然捶朵,這些是對UDP等上級協(xié)議透明的,UDP不需要關心IP協(xié)議層對數(shù)據(jù)如何分片狂男,下一個章節(jié)將會稍微討論一些分片的策略综看。

IP分片

IP在從上層接到數(shù)據(jù)以后,要根據(jù)IP地址來判斷從那個接口發(fā)送數(shù)據(jù)(通過選路)岖食,并進行MTU的查詢红碑,如果數(shù)據(jù)大小超過MTU就進行數(shù)據(jù)分片。數(shù)據(jù)的分片是對上層和下層透明泡垃,而數(shù)據(jù)也只是到達目的地還會被重新組裝句喷,不過不用擔心,IP層提供了足夠的信息進行數(shù)據(jù)的再組裝兔毙。

在IP頭里面唾琼,16bit識別號唯一記錄了一個IP包的ID,具有同一個ID的IP片將會被重新組裝;而13位片偏移則記錄了某IP片相對整個包的位置澎剥;而這兩個表示中間的3bit標志則標示著該分片后面是否還有新的分片锡溯。這三個標示就組成了IP分片的所有信息,接受方就可以利用這些信息對IP數(shù)據(jù)進行重新組織(就算是后面的分片比前面的分片先到哑姚,這些信息也是足夠了)祭饭。

因為分片技術在網絡上被經常的使用,所以偽造IP分片包進行流氓攻擊的軟件和人也就層出不窮叙量。

可以用Trancdroute程序來進行簡單的MTU偵測倡蝙。請參看教材。

3.UDP和ARP之間的交互式用

這是不常被人注意到的一個細節(jié)绞佩,這是針對一些系統(tǒng)地實現(xiàn)來說的寺鸥。當ARP緩存還是空的時候猪钮。UDP在被發(fā)送之前一定要發(fā)送一個ARP請求來獲得目的主機的MAC地址,如果這個UDP的數(shù)據(jù)包足夠大胆建,大到IP層一定要對其進行分片的時候烤低,想象中,該UDP數(shù)據(jù)包的第一個分片會發(fā)出一個ARP查詢請求笆载,所有的分片都非等到這個查詢完成以后再發(fā)送扑馁。事實上是這樣嗎?
結果是凉驻,某些系統(tǒng)會讓每一個分片都發(fā)送一個ARP查詢腻要,所有的分片都在等待,但是接受到第一個回應的時候涝登,主機卻只發(fā)送了最后一個數(shù)據(jù)片而拋棄了其他雄家,這實在是讓人匪夷所思。這樣缀拭,因為分片的數(shù)據(jù)不能被及時組裝,接受主機將會在一段時間內將永遠無法組裝的IP數(shù)據(jù)包拋棄填帽,并且發(fā)送組裝超時的ICMP報文(其實很多系統(tǒng)不產生這個差錯)蛛淋,以保證接受主機自己的接收端緩存不被那些永遠得不到組裝的分片充滿。

4.ICMP源站抑制差錯

當目標主機的處理速度趕不上數(shù)據(jù)接收的速度篡腌,因為接受主機的IP層緩存會被占滿褐荷,所以主機就會發(fā)出一個“我受不了”的一個ICMP報文。

5.UDP服務器設計

UDP協(xié)議的某些特性將會影響我們的服務器程序設計嘹悼,大致總結如下:
關于客戶IP和地址:服務器必須有根據(jù)客戶IP地址和端口號判斷數(shù)據(jù)包是否合法的能力(這似乎要求每一個服務器都要具備)
關于目的地址:服務器必須要有過濾廣播地址的能力叛甫。
關于數(shù)據(jù)輸入:通常服務器系統(tǒng)的每一個端口號都會和一塊輸入緩沖區(qū)對應,進來的輸入根據(jù)先來后到的原則等待服務器的處理杨伙,所以難免會出現(xiàn)緩沖區(qū)溢出的問題其监,這種情況下,UDP數(shù)據(jù)包可能會被丟棄限匣,而應用服務器程序本身并不知道這個問題抖苦。
服務器應該限制本地IP地址,就是說它應該可以把自己綁定到某一個網絡接口的某一個端口上米死。


廣播和多播锌历,IGMP協(xié)議

1.單播,多播峦筒,廣播的介紹

1.1.單播(unicast)

單播是說究西,對特定的主機進行數(shù)據(jù)傳送。例如給某一個主機發(fā)送IP數(shù)據(jù)包物喷。這時候卤材,數(shù)據(jù)鏈路層給出的數(shù)據(jù)頭里面是非常具體的目的地址遮斥,對于以太網來 說,就是網卡的MAC地址(不是FF-FF-FF-FF-FF-FF這樣的地址)。現(xiàn)在的具有路由功能的主機應該可以將單播數(shù)據(jù)定向轉發(fā),而目的主機的網 絡接口則可以過濾掉和自己MAC地址不一致的數(shù)據(jù)铡羡。

1.2.廣播(unicast)

廣播是主機針對某一個網絡上的所有主機發(fā)送數(shù)據(jù)包蜕便。這個網絡可能是網絡,可能是子網捶枢,還可能是所有的子網。如果是網絡,例如A類網址的廣播就是 netid.255.255.255吝镣,如果是子網,則是netid.netid.subnetid.255昆庇;如果是所有的子網(B類IP)則是則是 netid.netid.255.255末贾。廣播所用的MAC地址FF-FF-FF-FF-FF-FF。網絡內所有的主機都會收到這個廣播數(shù)據(jù)整吆,網卡只要把 MAC地址為FF-FF-FF-FF-FF-FF的數(shù)據(jù)交給內核就可以了拱撵。一般說來ARP,或者路由協(xié)議RIP應該是以廣播的形式播發(fā)的表蝙。

1.3.多播(multicast)

可以說廣播是多播的特例拴测,多播就是給一組特定的主機(多播組)發(fā)送數(shù)據(jù),這樣府蛇,數(shù)據(jù)的播發(fā)范圍會小一些(實際上播發(fā)的范圍一點也沒有變小)集索,多播的MAC地址是最高字節(jié)的低位為一,例 如01-00-00-00-00-00汇跨。多播組的地址是D類IP务荆,規(guī)定是224.0.0.0-239.255.255.255。

雖然多播較特殊穷遂,但是究其原理函匕,多播的數(shù)據(jù)還是要通過數(shù)據(jù)鏈路層進行MAC地址綁定然后進行發(fā)送。所以一個以太網卡在綁定了一個多播IP地址之后蚪黑,必定還要綁定一個多播的MAC地址浦箱,才能使得其可以像單播那樣工作。這個多播的IP和多播MAC地址有一個對應的算法祠锣,在書的p133到p134之間酷窥。可以看到這個對應不是一一對應的伴网,主機還是要對多播數(shù)據(jù)進行過濾蓬推。

個人的看法:

廣播和多播的性質是一樣的,路由器會把數(shù)據(jù)放到局域網里面澡腾,然后網卡對這些數(shù)據(jù)進行過濾沸伏,只拿到自己打算要的數(shù)據(jù)糕珊,比如自己感興趣的多 播數(shù)據(jù),自己感興趣的組播數(shù)據(jù)毅糟。當一個主機運行了一個處理某一個多播IP的進程的時候红选,這個進程會給網卡綁定一個虛擬的多播mac地址,并做出來一個多播 ip姆另。這樣喇肋,網卡就會讓帶有這個多播mac地址的數(shù)據(jù)進來,從而實現(xiàn)通信迹辐,而那些沒有監(jiān)聽這些數(shù)據(jù)的主機就會把這些數(shù)據(jù)過濾掉蝶防,換句話說,多播明吩,是讓主機的內核輕松了间学,而網卡,對不起印荔,您就累點吧低葫。

一些文章也印證了這種想法,最明顯的就是局域網監(jiān)聽的原理仍律、實現(xiàn)與防范

2.一些驗證性實驗

這些實驗并不是很復雜嘿悬,我們只是要ping一下一般的ip和一個廣播地址。首先我ping一下自己所在的子網的某一臺主機:

        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一個廣播地址呢茶行?結果如下:

        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返回了一些隨機的ip的結果登钥,這些ip都是與主機在同一子網內的ip畔师。我們可以看到,廣播實際上是給處于子網內的所有ip發(fā)信牧牢。

再來一個多播的例子看锉,但是要實現(xiàn)這個多播并不容易,因為我不知道網絡內有多少個多播組塔鳍,就只好利用幾個特殊的多播地址來驗證了伯铣。

對于多播地址,有幾個特殊的多播地址被占用轮纫,他們是

224.0.0.1--該子網內所有的系統(tǒng)組腔寡。
224.0.0.2--該子網內所有的路由器。
224.0.1.1--網絡實現(xiàn)協(xié)議NTP專用IP掌唾。
224.0.0.9--RIPv2專用IP

所以只要ping這幾個IP放前,就應該能得到一些結果忿磅,比如說我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只返回了一個ip的回應凭语。而這個就是我的網關的地址葱她,這也驗證了224.0.0.2是所有路由器的多播(組播)地址

3.IGMP協(xié)議

IGMP的作用在于,讓其他所有需要知道自己處于哪個多播組的主機和路由器知道自己的狀態(tài)似扔。一般多播路由器根本不需要知道某一個多播組里面有多少個主機吨些,而只要知道自己的子網內還有沒有處于某個多播組的主機就可以了。只要某一個多播組還有一臺主機虫几,多播路由器就會把數(shù)據(jù)傳輸出去锤灿,這樣,接受方就會通過網卡過濾功能來得到自己想要的數(shù)據(jù)辆脸。為了知道多播組的信息但校,多播路由器需要定時的發(fā)送IGMP查詢,IGMP的格式可以看書啡氢,各個多播組里面的主機要根據(jù)查詢來回復自己的狀態(tài)状囱。路由器來決定有幾個多播組,自己要對某一個多播組發(fā)送什么樣的數(shù)據(jù)倘是。

這種查詢回應數(shù)據(jù)報的TTL一般是1亭枷,而且就算是出錯也不產生ICMP差錯(沒必要)。


DNS域名系統(tǒng)

前面已經提到了訪問一臺機器要靠IP地址和MAC地址搀崭,其中叨粘,MAC地址可以通過ARP協(xié)議得到,所以這對用戶是透明的瘤睹,但是IP地址就不行升敲,無論如何用戶都需要用一個指定的IP來訪問一臺計算機,而IP地址又非常不好記轰传,于是就出現(xiàn)了DNS系統(tǒng)驴党。

1.DNS系統(tǒng)介紹

DNS的全稱是Domain Name System。它負責把FQDN(就是以"."分隔結尾的名字)翻譯成一個IP获茬。最初的DNS系統(tǒng)使用的是一個巨大的hosts.txt文件港庄,可是一段時間以后,就不得不用數(shù)據(jù)庫來代替hosts.txt文件恕曲,最終發(fā)展到了現(xiàn)在的分布式數(shù)據(jù)庫鹏氧。

從書中的143頁可以看到,DNS系統(tǒng)是一個巨大的樹佩谣,最上方有一個無名樹根把还,下一層是arpa,com,edu,gov,int,mil,us, cn。等等,其中arpa笨篷,是域名反解析樹的頂端瞳秽;而com,edu,等域名本來只用在美國(這就是技術特權)率翅,但是現(xiàn)在幾乎全世界通用练俐;而us, cn冕臭,等叫做國家域腺晾。

這個樹里面的域名并不是統(tǒng)一管理的,網絡信息中心(NIS)負責分配頂級域合委派其他制定地區(qū)域的授權機構辜贵。

一個獨立管理的DNS子樹叫做zone悯蝉,最常見的區(qū)域就是二級域名,比如說.com.cn托慨。我們還可以把這個二級域名給劃分成更小的區(qū)域鼻由,比如說sina.com.cn。

DNS系統(tǒng)是一個分布式的數(shù)據(jù)庫厚棵,當一個數(shù)據(jù)庫發(fā)現(xiàn)自己并沒有某查詢所需要的數(shù)據(jù)的時候蕉世,它將把查詢轉發(fā)出去,而轉發(fā)的目的地通常是根服務器婆硬,根服務器從上至下層層轉發(fā)查詢狠轻,直到找到目標為止。DNS還有一個特點就是使用高速緩存彬犯,DNS把查詢過的數(shù)據(jù)緩存在某處向楼,便于下次查詢時使用。

2.DNS協(xié)議

DNS報文定義了一個既可以查詢也可以響應的報文格式谐区。具體格式可以看P145頁湖蜕。對各個字段簡單解釋如下
最前面的16個bit唯一的標示了問題號碼,用于查詢端區(qū)別自己的查詢卢佣。
緊接著的16個bit又可以做進一步的細分重荠,標示了報文的性質和一些細節(jié)箭阶,比如說是查詢報文還是響應報文虚茶,需要遞歸查詢與否(一般服務器都支持遞歸查詢,而且不需要任何設置仇参,BIND就是這樣)
查詢問題后面有查詢類型嘹叫,包括A,NS诈乒,CNAME罩扇,PTR,HINFO,MX喂饥,如果熟悉BIND的話消约,就知道在zong的配置文件里面,每一條記錄都記載了各自的類型员帮,比如A就是IP地址或粮,NS就是名字服務器。
響應報文可以回復多個IP捞高,也就是說氯材,域名可以和多個IP地址對應,并且有很多CNAME硝岗。

3.反向查詢

正向查詢指的是通過域名得到IP的查詢氢哮,而反向查詢就是通過IP得到域名。例如用host命令型檀,host ip就可以得到服務器的域名冗尤,host domainName 就得到IP。
稍微知道一點數(shù)據(jù)結構的人都能意識到胀溺,在正向查詢的域里面做反向查詢生闲,其做法只有遍歷整個數(shù)據(jù)集合----對于DNS來說,那就是遍歷整個數(shù)據(jù)庫月幌, 這將帶來巨大的負擔碍讯,所以DNS采取了另一種方法,使用另一棵子樹來維護IP-〉域名的對應表扯躺。這個子樹的根節(jié)點是in-addr.arpa,而一個IP 例如192.168.11.2)所具有的DNS地址就是 2.11.168.192.in-addr.arpa(ip倒置)捉兴。在DNS系統(tǒng)里面,一個反向地址對應一個PTR紀錄(對應A紀錄)录语,所以反向查詢又叫 做指針(PTR)查詢倍啥。

4.其他問題的討論

4.1.DNS服務器高速緩存

BIND9默認是作為一個高速緩存服務器,其將所有的查詢都轉交到根服務器去澎埠,然后得到結果并放在本地的緩沖區(qū)虽缕,以加快查詢速度。如果有興趣可以安裝一個BIND9來嘗試一下蒲稳。而自己定義的zone則可以規(guī)定其在緩存中的時間氮趋,一般是1天(就是配置文件中的1D)。

4.2.用UDP還是TCP

DNS服務器支持TCP和UDP兩種協(xié)議的查詢方式江耀,而且端口都是53剩胁。而大多數(shù)的查詢都是UDP查詢的,一般需要TCP查詢的有兩種情況:
當查詢數(shù)據(jù)多大以至于產生了數(shù)據(jù)截斷(TC標志為1)祥国,這時昵观,需要利用TCP的分片能力來進行數(shù)據(jù)傳輸(看TCP的相關章節(jié))晾腔。
當主(master)服務器和輔(slave)服務器之間通信,輔服務器要拿到主服務器的zone信息的時候啊犬。


TCP協(xié)議概述

TCP和UDP處在同一層---運輸層灼擂,但是TCP和UDP最不同的地方是,TCP提供了一種可靠的數(shù)據(jù)傳輸服務觉至,TCP是面向連接的缤至,也就是說,利用TCP通信的兩臺主機首先要經歷一個“撥打電話”的過程康谆,等到通信準備結束才開始傳輸數(shù)據(jù)领斥,最后結束通話。所以TCP要比UDP可靠的多沃暗,UDP是把數(shù)據(jù)直接發(fā)出去月洛,而不管對方是不是在收信,就算是UDP無法送達孽锥,也不會產生ICMP差錯報文嚼黔,這一經時重申了很多遍了。

把TCP保證可靠性的簡單工作原理摘抄如下:

應用數(shù)據(jù)被分割成TCP認為最適合發(fā)送的數(shù)據(jù)塊惜辑。這和UDP完全不同唬涧,應用程序產生的數(shù)據(jù)報長度將保持不變。由TCP傳遞給IP的信息單位稱為報文段或段( segment)(參見圖1 - 7)盛撑。在1 8.4節(jié)我們將看到TCP如何確定報文段的長度碎节。
當TCP發(fā)出一個段后,它啟動一個定時器抵卫,等待目的端確認收到這個報文段狮荔。如果不能及時收到一個確認,將重發(fā)這個報文段介粘。在第21章我們將了解TCP協(xié)議中自適應的超時及重傳策略殖氏。
當TCP收到發(fā)自TCP連接另一端的數(shù)據(jù),它將發(fā)送一個確認姻采。這個確認不是立即發(fā)送雅采,通常將推遲幾分之一秒,這將在1 9.3節(jié)討論慨亲。
TCP將保持它首部和數(shù)據(jù)的檢驗和婚瓜。這是一個端到端的檢驗和,目的是檢測數(shù)據(jù)在傳輸過程中的任何變化巡雨。如果收到段的檢驗和有差錯闰渔,TP將丟棄這個報文段和不確認收到此報文段(希望發(fā)端超時并重發(fā))席函。
既然TCP報文段作為IP數(shù)據(jù)報來傳輸铐望,而IP數(shù)據(jù)報的到達可能會失序,因此TCP報文段 的到達也可能會失序。如果必要正蛙, TCP將對收到的數(shù)據(jù)進行重新排序督弓,將收到的數(shù)據(jù)以正確的順序交給應用層。
TCP還能提供流量控制乒验。TCP連接的每一方都有固定大小的緩沖空間愚隧。TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機致使較慢主機的緩沖區(qū)溢出锻全。

從這段話中可以看到狂塘,TCP中保持可靠性的方式就是超時重發(fā),這是有道理的鳄厌,雖然TCP也可以用各種各樣的ICMP報文來處理這些荞胡,但是這也不是可靠的,最可靠的方式就是只要不得到確認了嚎,就重新發(fā)送數(shù)據(jù)報泪漂,直到得到對方的確認為止。
TCP的首部和UDP首部一樣歪泳,都有發(fā)送端口號和接收端口號萝勤。但是顯然,TCP的首部信息要比UDP的多呐伞,可以看到敌卓,TCP協(xié)議提供了發(fā)送和確認所需要的所有必要的信息。這在P171-173有詳細地介紹伶氢〖侔ィ可以想象一個TCP數(shù)據(jù)的發(fā)送應該是如下的一個過程。

雙方建立連接

發(fā)送方給接受方TCP數(shù)據(jù)報鞍历,然后等待對方的確認TCP數(shù)據(jù)報舵抹,如果沒有,就重新發(fā)劣砍,如果有惧蛹,就發(fā)送下一個數(shù)據(jù)報。
接受方等待發(fā)送方的數(shù)據(jù)報刑枝,如果得到數(shù)據(jù)報并檢驗無誤香嗓,就發(fā)送ACK(確認)數(shù)據(jù)報,并等待下一個TCP數(shù)據(jù)報的到來装畅。直到接收到FIN(發(fā)送完成數(shù)據(jù)報)
中止連接

可以想見靠娱,為了建立一個TCP連接,系統(tǒng)可能會建立一個新的進程(最差也是一個線程)掠兄,來進行數(shù)據(jù)的傳送像云。


TCP連接的建立與中止

TCP是一個面向連接的協(xié)議锌雀,所以在連接雙方發(fā)送數(shù)據(jù)之前,都需要首先建立一條連接迅诬。

這和前面講到的協(xié)議完全不同腋逆。前面講的所有協(xié)議都只是發(fā)送數(shù)據(jù)而已,大多數(shù)都不關心發(fā)送的數(shù)據(jù)是不是送到侈贷,UDP尤其明顯惩歉,從編程的角度來說,UDP編程也要簡單的多----UDP都不用考慮數(shù)據(jù)分片俏蛮。

書中用telnet登陸退出來解釋TCP協(xié)議連接的建立和中止的過程撑蚌,可以看到:

TCP連接的建立可以簡單的稱為三次握手,而連接的中止則可以叫做四次握手搏屑。

1.連接的建立

在建立連接的時候锨并,客戶端首先向服務器申請打開某一個端口(用SYN段等于1的TCP報文),然后服務器端發(fā)回一個ACK報文通知客戶端請求報文收到睬棚,客戶端收到確認報文以后再次發(fā)出確認報文確認剛才服務器端發(fā)出的確認報文(繞口么)第煮,至此,連接的建立完成抑党。這就叫做三次握手包警。如果打算讓雙方都做好準備的話,一定要發(fā)送三次報文底靠,而且只需要三次報文就可以了害晦。
可以想見,如果再加上TCP的超時重傳機制暑中,那么TCP就完全可以保證一個數(shù)據(jù)包被送到目的地壹瘟。

2.結束連接

TCP有一個特別的概念叫做half-close,這個概念是說鳄逾,TCP的連接是全雙工(可以同時發(fā)送和接收)連接稻轨,因此在關閉連接的時候,必須關閉傳和送兩個方向上的連接雕凹∨咕悖客戶機給服務器一個FIN為1的TCP報文,然后服務器返回給客戶端一個確認ACK報文枚抵,并且發(fā)送一個FIN報文线欲,當客戶機回復ACK報文后(四次握手),連接就結束了汽摹。

3.最大報文長度

在建立連接的時候李丰,通信的雙方要互相確認對方的最大報文長度(MSS),以便通信逼泣。一般這個SYN長度是MTU減去固定IP首部和TCP首部長度趴泌。對于一個以太網舟舒,一般可以達到1460字節(jié)。當然如果對于非本地的IP踱讨,這個MSS可能就只有536字節(jié)魏蔗,而且砍的,如果中間的傳輸網絡的MSS更佳的小的話痹筛,這個值還會變得更小。

4.TCP的狀態(tài)遷移圖

書P182頁給出了TCP的狀態(tài)圖廓鞠,這是一個看起來比較復雜的狀態(tài)遷移圖帚稠,因為它包含了兩個部分---服務器的狀態(tài)遷移和客戶端的狀態(tài)遷移,如果從某一個角度出發(fā)來看這個圖床佳,就會清晰許多滋早,這里面的服務器和客戶端都不是絕對的,發(fā)送數(shù)據(jù)的就是客戶端砌们,接受數(shù)據(jù)的就是服務器杆麸。

4.1.客戶端應用程序的狀態(tài)遷移圖

客戶端的狀態(tài)可以用如下的流程來表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情況下應該有的流程锰蓬,從書中的圖中可以看到株灸,在建立連接時,當客戶端收到SYN報文的ACK以后考杉,客戶端就打開了數(shù)據(jù)交互地連接影兽。而結束連接則通常是客戶端主動結束的揭斧,客戶端結束應用程序以后,需要經歷FIN_WAIT_1峻堰,F(xiàn)IN_WAIT_2等狀態(tài)讹开,這些狀態(tài)的遷移就是前面提到的結束連接的四次握手。

4.2.服務器的狀態(tài)遷移圖

服務器的狀態(tài)可以用如下的流程來表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
在建立連接的時候捐名,服務器端是在第三次握手之后才進入數(shù)據(jù)交互狀態(tài)旦万,而關閉連接則是在關閉連接的第二次握手以后(注意不是第四次)。而關閉以后還要等待客戶端給出最后的ACK包才能進入初始的狀態(tài)镶蹋。

4.3.其他狀態(tài)遷移

書中的圖還有一些其他的狀態(tài)遷移纸型,這些狀態(tài)遷移針對服務器和客戶端兩方面的總結如下
LISTEN->SYN_SENT,對于這個解釋就很簡單了梅忌,服務器有時候也要打開連接的嘛狰腌。
SYN_SENT->SYN收到,服務器和客戶端在SYN_SENT狀態(tài)下如果收到SYN數(shù)據(jù)報牧氮,則都需要發(fā)送SYN的ACK數(shù)據(jù)報并把自己的狀態(tài)調整到SYN收到狀態(tài)琼腔,準備進入ESTABLISHED
SYN_SENT->CLOSED,在發(fā)送超時的情況下踱葛,會返回到CLOSED狀態(tài)丹莲。
SYN_收到->LISTEN光坝,如果受到RST包,會返回到LISTEN狀態(tài)甥材。
SYN_收到->FIN_WAIT_1盯另,這個遷移是說,可以不用到ESTABLISHED狀態(tài)洲赵,而可以直接跳轉到FIN_WAIT_1狀態(tài)并等待關閉鸳惯。

4.4. 2MSL等待狀態(tài)

書中給的圖里面,有一個TIME_WAIT等待狀態(tài)叠萍,這個狀態(tài)又叫做2MSL狀態(tài)芝发,說的是在TIME_WAIT2發(fā)送了最后一個ACK數(shù)據(jù)報以后,要進入TIME_WAIT狀態(tài)苛谷,這個狀態(tài)是防止最后一次握手的數(shù)據(jù)報沒有傳送到對方那里而準備的(注意這不是四次握手辅鲸,這是第四次握手的保險狀態(tài))。這個狀態(tài)在很大程度上保證了雙方都可以正常結束腹殿,但是独悴,問題也來了。
由于插口的2MSL狀態(tài)(插口是IP和端口對的意思锣尉,socket)刻炒,使得應用程序在2MSL時間內是無法再次使用同一個插口的,對于客戶程序還好一些悟耘,但是對于服務程序落蝙,例如httpd,它總是要使用同一個端口來進行服務暂幼,而在2MSL時間內筏勒,啟動httpd就會出現(xiàn)錯誤(插口被使用)。為了避免這個錯誤旺嬉,服務器給出了一個平靜時間的概念管行,這是說在2MSL時間內,雖然可以重新啟動服務器邪媳,但是這個服務器還是要平靜的等待2MSL時間的過去才能進行下一次連接捐顷。

4.5.FIN_WAIT_2狀態(tài)

這就是著名的半關閉的狀態(tài)了,這是在關閉連接時雨效,客戶端和服務器兩次握手之后的狀態(tài)迅涮。在這個狀態(tài)下,應用程序還有接受數(shù)據(jù)的能力徽龟,但是已經無法發(fā)送數(shù)據(jù)叮姑,但是也有一種可能是,客戶端一直處于FIN_WAIT_2狀態(tài),而服務器則一直處于WAIT_CLOSE狀態(tài)传透,而直到應用層來決定關閉這個狀態(tài)耘沼。

5.RST,同時打開和同時關閉

RST是另一種關閉連接的方式朱盐,應用程序應該可以判斷RST包的真實性群嗤,即是否為異常中止。而同時打開和同時關閉則是兩種特殊的TCP狀態(tài)兵琳,發(fā)生的概率很小狂秘。

6.TCP服務器設計

前面曾經講述過UDP的服務器設計,可以發(fā)現(xiàn)UDP的服務器完全不需要所謂的并發(fā)機制闰围,它只要建立一個數(shù)據(jù)輸入隊列就可以赃绊。但是TCP不同既峡,TCP服務器對于每一個連接都需要建立一個獨立的進程(或者是輕量級的羡榴,線程),來保證對話的獨立性运敢。所以TCP服務器是并發(fā)的校仑。而且TCP還需要配備一個呼入連接請求隊列(UDP服務器也同樣不需要),來為每一個連接請求建立對話進程传惠,這也就是為什么各種TCP服務器都有一個最大連接數(shù)的原因迄沫。而根據(jù)源主機的IP和端口號碼,服務器可以很輕松的區(qū)別出不同的會話卦方,來進行數(shù)據(jù)的分發(fā)羊瘩。

掌握本章的狀態(tài)遷移圖才是學習本章的關鍵。


TCP交互數(shù)據(jù)流盼砍,成塊數(shù)據(jù)流

目前建立在TCP協(xié)議上的網絡協(xié)議特別多尘吗,有telnet,ssh浇坐,有ftp睬捶,有http等等。這些協(xié)議又可以根據(jù)數(shù)據(jù)吞吐量來大致分成兩大類:

(1)交互數(shù)據(jù)類型近刘,例如telnet擒贸,ssh,這種類型的協(xié)議在大多數(shù)情況下只是做小流量的數(shù)據(jù)交換觉渴,比如說按一下鍵盤介劫,回顯一些文字等等。

(2)數(shù)據(jù)成塊類型案淋,例如ftp座韵,這種類型的協(xié)議要求TCP能盡量的運載數(shù)據(jù),把數(shù)據(jù)的吞吐量做到最大哎迄,并盡可能的提高效率回右。針對這兩種情況隆圆,TCP給出了兩種不同的策略來進行數(shù)據(jù)傳輸。

1.TCP的交互數(shù)據(jù)流

對于交互性要求比較高的應用翔烁,TCP給出兩個策略來提高發(fā)送效率和減低網絡負擔:

  • 捎帶ACK渺氧。

  • Nagle算法(一次盡量多的發(fā)數(shù)據(jù))。

通常蹬屹,在網絡速度很快的情況下侣背,比如用lo接口進行telnet通信,當按下字母鍵并要求回顯的時候慨默,客戶端和服務器將經歷 發(fā)送按鍵數(shù)據(jù)->服務器發(fā)送按鍵數(shù)據(jù)的ack -> 服務器端發(fā)送回顯數(shù)據(jù)->客戶端發(fā)送回顯數(shù)據(jù)的ACK的過程贩耐,而其中的數(shù)據(jù)流量將是40bit + 41bit+41bit+40bit = 162bit,如果在廣域網里面厦取,這種小分組的TCP流量將會造成很大的網絡負擔潮太。

1.1.捎帶ACK的發(fā)送方式

這個策略是說,當主機收到遠程主機的TCP數(shù)據(jù)報之后虾攻,通常不馬上發(fā)送ACK數(shù)據(jù)報铡买,而是等上一個短暫的時間,如果這段時間里面主機還有發(fā)送到遠程主機的TCP數(shù)據(jù)報霎箍,那么就把這個ACK數(shù)據(jù)報“捎帶”著發(fā)送出去奇钞,把本來兩個TCP數(shù)據(jù)報整合成一個發(fā)送。一般的漂坏,這個時間是200ms景埃。可以明顯地看到這個策略可以把TCP數(shù)據(jù)報的利用率提高很多顶别。

1.2.Nagle算法

上過bbs的人應該都會有感受谷徙,就是在網絡慢的時候發(fā)貼,有時鍵入一串字符串以后筋夏,經過一段時間蒂胞,客戶端“發(fā)瘋”一樣突然回顯出很多內容,就好像數(shù)據(jù)一下子傳過來了一樣条篷,這就是Nagle算法的作用骗随。

Nagle算法是說,當主機A給主機B發(fā)送了一個TCP數(shù)據(jù)報并進入等待主機B的ACK數(shù)據(jù)報的狀態(tài)時赴叹,TCP的輸出緩沖區(qū)里面只能有一個TCP數(shù)據(jù)報鸿染,并且,這個數(shù)據(jù)報不斷地收集后來的數(shù)據(jù)乞巧,整合成一個大的數(shù)據(jù)報涨椒,等到B主機的ACK包一到,就把這些數(shù)據(jù)“一股腦”的發(fā)送出去。

雖然這樣的描述有些不準確蚕冬,但還算形象和易于理解免猾,我們同樣可以體會到這個策略對于低減網絡負擔的好處。

在編寫插口程序的時候囤热,可以通過TCP_NODELAY來關閉這個算法猎提。并且,使用這個算法看情況的旁蔼,比如基于TCP的X窗口協(xié)議锨苏,如果處理鼠標事件時還是用這個算法,那么“延遲”可就非常大了棺聊。

2.TCP的成塊數(shù)據(jù)流

對于FTP這樣對于數(shù)據(jù)吞吐量有較高要求的要求伞租,將總是希望每次盡量多的發(fā)送數(shù)據(jù)到對方主機,就算是有點“延遲”也無所謂限佩。TCP也提供了一整套的策略來支持這樣的需求葵诈。TCP協(xié)議中有16個bit表示“窗口”的大小,這是這些策略的核心犀暑。

2.1.傳輸數(shù)據(jù)時ACK的問題

在解釋滑動窗口前驯击,需要看看ACK的應答策略烁兰,一般來說耐亏,發(fā)送端發(fā)送一個TCP數(shù)據(jù)報,那么接收端就應該發(fā)送一個ACK數(shù)據(jù)報沪斟。但是事實上卻不是這樣广辰,發(fā)送端將會連續(xù)發(fā)送數(shù)據(jù)盡量填滿接受方的緩沖區(qū),而接受方對這些數(shù)據(jù)只要發(fā)送一個ACK報文來回應就可以了主之,這就是ACK的累積特性择吊,這個特性大大減少了發(fā)送端和接收端的負擔。

2.2.滑動窗口

滑動窗口本質上是描述接受方的TCP數(shù)據(jù)報緩沖區(qū)大小的數(shù)據(jù)槽奕,發(fā)送方根據(jù)這個數(shù)據(jù)來計算自己最多能發(fā)送多長的數(shù)據(jù)几睛。如果發(fā)送方收到接受方的窗口大小為0的TCP數(shù)據(jù)報,那么發(fā)送方將停止發(fā)送數(shù)據(jù)粤攒,等到接受方發(fā)送窗口大小不為0的數(shù)據(jù)報的到來所森。

書中的P211和P212很好的解釋了這一點。

關于滑動窗口協(xié)議夯接,書上還介紹了三個術語焕济,分別是:

窗口合攏:當窗口從左邊向右邊靠近的時候,這種現(xiàn)象發(fā)生在數(shù)據(jù)被發(fā)送和確認的時候盔几。
窗口張開:當窗口的右邊沿向右邊移動的時候晴弃,這種現(xiàn)象發(fā)生在接受端處理了數(shù)據(jù)以后。
窗口收縮:當窗口的右邊沿向左邊移動的時候,這種現(xiàn)象不常發(fā)生上鞠。

TCP就是用這個窗口际邻,慢慢的從數(shù)據(jù)的左邊移動到右邊,把處于窗口范圍內的數(shù)據(jù)發(fā)送出去(但不用發(fā)送所有芍阎,只是處于窗口內的數(shù)據(jù)可以發(fā)送枯怖。)。這就是窗口的意義能曾。圖20-6解釋了這一點度硝。窗口的大小是可以通過socket來制定的,4096并不是最理想的窗口大小寿冕,而16384則可以使吞吐量大大的增加蕊程。

2.3.數(shù)據(jù)擁塞

上面的策略用于局域網內傳輸還可以,但是用在廣域網中就可能會出現(xiàn)問題驼唱,最大的問題就是當傳輸時出現(xiàn)了瓶頸(比如說一定要經過一個slip低速鏈路)所產生的大量數(shù)據(jù)堵塞問題(擁塞)藻茂,為了解決這個問題,TCP發(fā)送方需要確認連接雙方的線路的數(shù)據(jù)最大吞吐量是多少玫恳。這辨赐,就是所謂的擁塞窗口。

擁塞窗口的原理很簡單京办,TCP發(fā)送方首先發(fā)送一個數(shù)據(jù)報掀序,然后等待對方的回應,得到回應后就把這個窗口的大小加倍惭婿,然后連續(xù)發(fā)送兩個數(shù)據(jù)報不恭,等到對方回應以后,再把這個窗口加倍(先是2的指數(shù)倍财饥,到一定程度后就變成現(xiàn)行增長换吧,這就是所謂的慢啟動),發(fā)送更多的數(shù)據(jù)報钥星,直到出現(xiàn)超時錯誤沾瓦,這樣,發(fā)送端就了解到了通信雙方的線路承載能力谦炒,也就確定了擁塞窗口的大小贯莺,發(fā)送方就用這個擁塞窗口的大小發(fā)送數(shù)據(jù)。要觀察這個現(xiàn)象是非常容易的编饺,我們一般在下載數(shù)據(jù)的時候乖篷,速度都是慢慢“沖起來的”

以上就是TCP數(shù)據(jù)傳輸?shù)拇笾铝鞒蹋m然并不細致透且,但是足以描述TCP的工作原理撕蔼,重點是TCP的流量控制原理豁鲤,滑動窗口,擁塞窗口鲸沮,ACK累計確認等知識點琳骡。


TCP的超時與重傳

超時重傳是TCP協(xié)議保證數(shù)據(jù)可靠性的另一個重要機制,其原理是在發(fā)送某一個數(shù)據(jù)以后就開啟一個計時器讼溺,在一定時間內如果沒有得到發(fā)送的數(shù)據(jù)報的ACK報文楣号,那么就重新發(fā)送數(shù)據(jù),直到發(fā)送成功為止怒坯。

1.超時

超時時間的計算是超時的核心部分炫狱,TCP要求這個算法能大致估計出當前的網絡狀況,雖然這確實很困難剔猿。要求精確的原因有兩個:

  • (1)定時長久會造成網絡利用率不高视译。

  • (2)定時太短會造成多次重傳,使得網絡阻塞归敬。所以酷含,書中給出了一套經驗公式,和其他的保證計時器準確的措施汪茧。

1.1.遞推公式概說

最早的TCP曾經用了一個非常簡單的公式來估計當前網絡的狀況椅亚,如下

       R<-aR+(1-a)M
       RTP=Rb

其中a是一個經驗系數(shù)為0.1,b通常為2舱污。注意呀舔,這是經驗,沒有推導過程慌闭,這個數(shù)值是可以被修改的别威。這個公式是說用舊的RTT(R)和新的RTT(M)綜合到一起來考慮新的RTT(R)的大小。但是驴剔,我們又看到,這種估計在網絡變化很大的情況下完全不能做出“靈敏的反應”(Jacoboson說的粥庄,不是偶說的丧失,呵呵),于是就有下面的修正公式:

     Err=M-A
     A<-A+gErr
     D<-D+h(|Err|-D)
     RTO=A+4D

具體的解釋請看書的228頁惜互,這個遞推公式甚至把方差這種統(tǒng)計概念也使用了進來布讹,使得偏差更加的小。而且训堆,必須要指出的是描验,這兩組公式更新,都是在數(shù)據(jù)成功傳輸?shù)那闆r下才進行坑鱼,在發(fā)生數(shù)據(jù)重新傳輸?shù)那闆r下膘流,并不使用上面的公式進行網絡估計絮缅,理由很簡單,因為程序已經不在正常狀態(tài)下了呼股,估計出來的數(shù)據(jù)也是沒有意義的耕魄。

1.2.RTO的初始化

RTO的初始化是由公式決定的,例如最初的公式彭谁,初始的值應該是1吸奴。而修正公式,初始RTO應該是A+4D缠局。

1.3.RTO的更新

當數(shù)據(jù)正常傳輸?shù)那闆r下则奥,我們就會用上面的公式來更新各個數(shù)據(jù),并重開定時器狭园,來保證下一個數(shù)據(jù)被順利傳輸逞度。要注意的是:重傳的情況下,RTO不用上面的公式計算妙啃,而采用一種叫做“指數(shù)退避”的方式档泽。例如:當RTO為1S的情況下,發(fā)生了數(shù)據(jù)重傳揖赴,我們就用RTO=2S的定時器來重新傳輸數(shù)據(jù)馆匿,下一次用4S。一直增加到64S為止燥滑。

1.4.估計器的初始化

在這里渐北,SYN用的估計器初始化似乎和傳輸用的估計器不一樣(我也沒有把握)造我的理解,在修正公式中铭拧,SYN的情況下赃蛛,A初始化為0,D初始化為3S。
而在得到傳輸?shù)谝粋€數(shù)據(jù)的ACK的時候搀菩,應該按照下面的公式進行初始化:
A=M+0.5
D=A/2

1.5.估計器的更新

和上面的討論差不多呕臂,就是在正常情況下,用上面的公式計算肪跋,在重傳的情況下歧蒋,不更新估計器的各種參數(shù)。原因還是因為估計不準確州既。

1.6.Karn算法

這不算是一個算法谜洽,這應該是一個策略,說的就是更新RTO和估計器的值的時機選擇問題吴叶,1.3.和1.5.所說得更新時機就是Karn算法阐虚。

1.7.計時器的使用

兩句話:一個連接中,有且僅有一個測量定時器被使用蚌卤。也就是說实束,如果TCP連續(xù)發(fā)出3組數(shù)據(jù)奥秆,只有一組數(shù)據(jù)會被測量。
ACK數(shù)據(jù)報不會被測量磕洪,原因很簡單吭练,沒有ACK的ACK回應可以供結束定時器測量。

2.重傳

有了超時就要有重傳析显,但是就算是重傳也是有策略的鲫咽,而不是將數(shù)據(jù)簡單的發(fā)送。

2.1.重傳時發(fā)送數(shù)據(jù)的大小

前面曾經提到過谷异,數(shù)據(jù)在傳輸?shù)臅r候不能只使用一個窗口協(xié)議分尸,我們還需要有一個擁塞窗口來控制數(shù)據(jù)的流量,使得數(shù)據(jù)不會一下子都跑到網路中引起“擁塞”歹嘹。也曾經提到過箩绍,擁塞窗口最初使用指數(shù)增長的速度來增加自身的窗口,直到發(fā)生超時重傳尺上,再進行一次微調材蛛。但是沒有提到,如何進行微調怎抛,擁塞避免算法和慢啟動門限就是為此而生卑吭。
所謂的慢啟動門限就是說,當擁塞窗口超過這個門限的時候马绝,就使用擁塞避免算法豆赏,而在門限以內就采用慢啟動算法。所以這個標準才叫做門限富稻,通常掷邦,擁塞窗口記做cwnd,慢啟動門限記做ssthresh椭赋。下面我們來看看擁塞避免和慢啟動是怎么一起工作的
算法概要(直接從書中拷貝)
對一個給定的連接抚岗,初始化cwnd為1個報文段,ssthresh為65535個字節(jié)纹份。
TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小苟跪。擁塞避免是發(fā)送方使用 的流量控制,而通告窗口則是接收方進行的流量控制蔓涧。前者是發(fā)送方感受到的網絡擁塞的估 計,而后者則與接收方在該連接上的可用緩存大小有關笋额。
當擁塞發(fā)生時(超時或收到重復確認)元暴,ssthresh被設置為當前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值,但最少為2個報文段)兄猩。此外茉盏,如果是超時引起了擁塞鉴未,則 cwnd被設置為1個報文段(這就是慢啟動)。
當新的數(shù)據(jù)被對方確認時鸠姨,就增加cwnd铜秆,但增加的方法依賴于我們是否正在進行慢啟動或擁塞避免。如果cwnd小于或等于ssthresh讶迁,則正在進行慢啟動连茧,否則正在進行擁塞避免。 慢啟動一直持續(xù)到我們回到當擁塞發(fā)生時所處位置的半時候才停止(因為我們記錄了在步驟2 中給我們制造麻煩的窗口大小的一半)巍糯,然后轉為執(zhí)行擁塞避免啸驯。

補充上面的擁塞避免公式在P238頁。

2.2.快速重傳和快速恢復算法

這是數(shù)據(jù)丟包的情況下給出的一種修補機制祟峦。一般來說罚斗,重傳發(fā)生在超時之后,但是如果發(fā)送端接受到3個以上的重復ACK的情況下宅楞,就應該意識到针姿,數(shù)據(jù)丟了,需要重新傳遞厌衙。這個機制是不需要等到重傳定時器溢出的距淫,所以叫做快速重傳,而重新傳遞以后迅箩,因為走的不是慢啟動而是擁塞避免算法溉愁,所以又稱為快速恢復算法。流程如下:

  • 當收到第3個重復的ACK時饲趋,將ssthresh設置為當前擁塞窗口cwnd的一半絮重。重傳丟失的 報文段炬灭。設置cwnd為ssthresh加上3倍的報文段大小。

  • 每次收到另一個重復的ACK時, cwnd增加1個報文段大小并發(fā)送1個分組(如果新的 cwnd允許發(fā)送)阶冈。

  • 當下一個確認新數(shù)據(jù)的ACK到達時,設置cwnd為ssthresh(在第1步中設置的值)楷拳。這個 ACK應該是在進行重傳后的一個往返時間內對步驟1中重傳的確認担巩。另外,這個ACK也應該 是對丟失的分組和收到的第1個重復的ACK之間的所有中間報文段的確認换棚。這一步采用的是擁塞避免式镐,因為當分組丟失時我們將當前的速率減半。

2.3.ICMP會引起重新傳遞么固蚤?

不會娘汞,TCP會堅持用自己的定時器,但TCP會保留下ICMP的錯誤并且通知用戶夕玩。

2.4.重新分組

TCP為了提高自己的效率你弦,允許再重新傳輸?shù)臅r候惊豺,只要傳輸包含重傳數(shù)據(jù)報文的報文就可以,而不用只重傳需要傳輸?shù)膱笪摹?/p>


TCP堅持定時器禽作,TCP笔粒活定時器

TCP一共有四個主要的定時器,前面已經講到了一個--超時定時器--是TCP里面最復雜的一個旷偿,另外的三個是:

堅持定時器
迸胨祝活定時器
2MSL定時器

其中堅持定時器用于防止通告窗口為0以后,雙方互相等待死鎖的情況狸捅;而敝则眩活定時器則用于處理半開放連接。

1.堅持定時器

堅持定時器的原理是簡單的尘喝,當TCP服務器收到了客戶端的0滑動窗口報文的時候磁浇,就啟動一個定時器來計時,并在定時器溢出的時候向向客戶端查詢窗口是否已經增大朽褪,如果得到非零的窗口就重新開始發(fā)送數(shù)據(jù)置吓,如果得到0窗口就再開一個新的定時器準備下一次查詢。通過觀察可以得知缔赠,TCP的堅持定時器使用1衍锚,2,4嗤堰,8戴质,16……64秒這樣的普通指數(shù)退避序列來作為每一次的溢出時間。

糊涂窗口綜合癥

TCP的窗口協(xié)議踢匣,會引起一種通常叫做糊涂窗口綜合癥的問題告匠,具體表現(xiàn)為,當客戶端通告一個小的非零窗口時离唬,服務器立刻發(fā)送小數(shù)據(jù)給客戶端并充滿其緩沖區(qū)后专,一來二去就會讓網絡中充滿小TCP數(shù)據(jù)報,從而影響網絡利用率输莺。對于發(fā)送方和接收端的這種糊涂行為戚哎。TCP給出了一些建議(或者是規(guī)定)。

接收方不通告小窗口嫂用。

通常的算法是接收方不通告一個比當前窗口大的窗口(可以為0)型凳,除非窗口可以增加一個報文段大小(也就是將要接收的MSS)或者可以增加接收方緩存空間的一半嘱函,不論實際有多少啰脚。

發(fā)送方避免出現(xiàn)糊涂窗口綜合癥的措施是只有以下條件之一滿足時才發(fā)送數(shù)據(jù):

  1. 可以發(fā)送一個滿長度的報文段;

  2. 可以發(fā)送至少是接收方通告窗口大小一半的報文段实夹;

  3. 可以發(fā)送任何數(shù)據(jù)并且不希望接收ACK(也就是說橄浓,我們沒有還未被確認的數(shù)據(jù))或者該連接上不能使用Nagle算法。

ok亮航,現(xiàn)在我們回憶一下荸实,可以發(fā)現(xiàn)TCP的很多規(guī)定都是為了在一次傳送中發(fā)送盡量多的數(shù)據(jù),例如捎帶ACK數(shù)據(jù)報文的策略缴淋,Nagle算法准给,重傳時發(fā)送包含原數(shù)據(jù)報文的策略,等等重抖。

2.甭兜活定時器

保活定時器更加的簡單钟沛,還記得FTP或者Http服務器都有Sesstion Time機制么畔规?因為TCP是面向連接的,所以就會出現(xiàn)只連接不傳送數(shù)據(jù)的“半開放連接”恨统,服務器當然要檢測到這種連接并且在某些情況下釋放這種連接叁扫,這就是保活定時器的作用畜埋。其時限根據(jù)服務器的實現(xiàn)不同而不通莫绣。另外要提到的是,當其中一端如果崩潰并重新啟動的情況下悠鞍,如果收到該端“前生”的倍允遥活探察,則要發(fā)送一個RST數(shù)據(jù)報文幫助另一端結束連接咖祭。

作者:SOMCENT
鏈接:http://www.reibang.com/p/0cf648510bce
來源:簡書
著作權歸作者所有掩宜。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處心肪。</pre>

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末锭亏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子硬鞍,更是在濱河造成了極大的恐慌慧瘤,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件固该,死亡現(xiàn)場離奇詭異锅减,居然都是意外死亡,警方通過查閱死者的電腦和手機伐坏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門怔匣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事每瞒〗鹈觯” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵剿骨,是天一觀的道長代芜。 經常有香客問我,道長浓利,這世上最難降的妖魔是什么挤庇? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮贷掖,結果婚禮上嫡秕,老公的妹妹穿的比我還像新娘。我一直安慰自己苹威,他們只是感情好昆咽,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屠升,像睡著了一般潮改。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腹暖,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天汇在,我揣著相機與錄音,去河邊找鬼脏答。 笑死糕殉,一個胖子當著我的面吹牛,可吹牛的內容都是我干的殖告。 我是一名探鬼主播阿蝶,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼黄绩!你這毒婦竟也來了羡洁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤爽丹,失蹤者是張志新(化名)和其女友劉穎筑煮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粤蝎,經...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡真仲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了初澎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秸应。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出软啼,到底是詐尸還是另有隱情桑谍,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布焰宣,位于F島的核電站霉囚,受9級特大地震影響,放射性物質發(fā)生泄漏匕积。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一榜跌、第九天 我趴在偏房一處隱蔽的房頂上張望闪唆。 院中可真熱鬧,春花似錦钓葫、人聲如沸悄蕾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帆调。三九已至,卻和暖如春豆同,著一層夾襖步出監(jiān)牢的瞬間番刊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工影锈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芹务,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓鸭廷,卻偏偏與公主長得像枣抱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辆床,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內容