http://www.cnblogs.com/vamei/archive/2012/12/02/2796988.htmlhtml
咱們已經在IP接力中介紹過,一個IP包分爲頭部(header)和數據(payload/data)兩部分。頭部是爲了實現IP通訊必須的附加信息,數據是IP通訊所要傳送的信息。算法
咱們看到,三個黃色區域跨越了IPv4和IPv6。Version(4位)用來代表IP協議版本,是IPv4仍是IPv6(IPv4, Version=0100; IPv6, Version=0110)。Source Adrresss和Destination Address分別爲發出地和目的地的IP地址。網絡
Time to Live 存活時間(Hop Limit in IPv6)。Time to Live最初是表示一個IP包的最大存活時間:若是IP包在傳輸過程當中超過Time to Live,那麼IP包就做廢。後來,IPv4的這個區域記錄一個整數(好比30),表示在IP包接力過程當中最多通過30個路由接力,若是超過30個路由接力,那麼這個IP包就做廢。IP包每通過一個路由器,路由器就給Time to Live減一。當一個路由器發現Time to Live爲0時,就再也不發送該IP包。IPv6中的Hop Limit區域記錄的也是最大路由接力數,與IPv4的功能相同。Time to Live/Hop Limit避免了IP包在互聯網中無限接力。優化
Type of Service 服務類型(Traffic Class in IPv6)。Type of Service最初是用來給IP包分優先級,好比語音通話須要實時性,因此它的IP包應該比Web服務的IP包有更高的優先級。然而,這個最初不錯的想法沒有被微軟採納。在Windows下生成的IP包都是相同的最高優先級,因此在當時形成Linux和Windows混合網絡中,Linux的IP傳輸會慢於Windows (僅僅是由於Linux更加守規矩!)。後來,Type of Service被實際分爲兩部分:Differentiated Service Field (DS, 前6位)和Explicit Congestion Nofification (ECN, 後2位),前者依然用來區分服務類型,然後者用於代表IP包途徑路由的交通情況。IPv6的Traffic Class也被如此分紅兩部分。經過IP包提供不一樣服務的想法,並針對服務進行不一樣的優化的想法已經產生好久了,但具體作法並無造成公認的協議。好比ECN區域,它用來表示IP包通過路徑的交通情況。若是接收者收到的ECN區域顯示路徑上的很擁擠,那麼接收者應該做出調整。但在實際上,許多接收者都會忽視ECN所包含的信息。交通情況的控制每每由更高層的好比TCP協議實現。spa
Protocol 協議(Next Header in IPv6)。Protocol用來講明IP包Payload部分所遵循的協議,也就是IP包之上的協議是什麼。它說明了IP包封裝的是一個怎樣的高層協議包(TCP? UDP?)。設計
Total Length, 以及IPv6中Payload Length的討論要和IHL區域放在一塊兒,咱們即將討論。htm
咱們看一下IPv4和IPv6的長度信息。IPv4頭部的長度。在頭部的最後,是options。每一個options有32位,是選填性質的區域。一個IPv4頭部能夠徹底沒有options區域。不考慮options的話,整個IPv4頭部有20 bytes(上面每行爲4 bytes)。但因爲有options的存在,整個頭部的總長度是變更的。咱們用IHL(Internet Header Length)來記錄頭部的總長度,用Total Length記錄整個IP包的長度。IPv6沒有options,它的頭部是固定的長度40 bytes,因此IPv6中並不須要IHL區域。Payload Length用來表示IPv6的數據部分的長度。整個IP包爲40 bytes + Payload Length。blog
IPv4中還有一個Header Checksum區域。這個checksum用於校驗IP包的頭部信息。Checksum與以前在小喇叭中提到的CRC算法並不相同。IPv6則沒有checksum區域。IPv6包的校驗依賴高層的協議來完成,這樣的好處是免去了執行checksum校驗所須要的時間,減少了網絡延遲 (latency)。ci
Identification, flags和fragment offset,這三個包都是爲碎片化(fragmentation)服務的。碎片化是指一個路由器將接收到的IP包分拆成多個IP包傳送,而接收這些「碎片」的路由器或者主機須要將「碎片」從新組合(reassembly)成一個IP包。不一樣的局域網所支持的最大傳輸單元(MTU, Maximum Transportation Unit)不一樣。若是一個IP包的大小超過了局域網支持的MTU,就須要在進入該局域網時碎片化傳輸(就好像方面面面餅太大了,必須掰碎才能放進碗裏)。碎片化會給路由器和網絡帶來很大的負擔。最好在IP包發出以前探測整個路徑上的最小MTU,IP包的大小不超過該最小MTU,就能夠避免碎片化。IPv6在設計上避免碎片化。每個IPv6局域網的MTU都必須大於等於1280 bytes。IPv6的默認發送IP包大小爲1280 bytes。路由
使人痛苦的碎片化
Flow Label是IPv6中新增的區域。它被用來提醒路由器來重複使用以前的接力路徑。這樣IP包能夠自動保持出發時的順序。這對於流媒體之類的應用有幫助。Flow label的進一步使用還在開發中。
IP協議在產生時是一個鬆散的網絡,這個網絡由各個大學的局域網相互鏈接成的,由一羣碰頭垢面的Geek維護。因此,IP協議認爲本身所處的環境是不可靠(unreliable)的:諸如路由器壞掉、實驗室失火、某個PhD踢掉電纜之類的事情隨時會發生。
不靠譜的網絡
這樣的兇險環境下,IP協議提供的傳送只能是「我盡力」 (best effort)式的。所謂的「我盡力」,其潛臺詞是,若是事情出錯不要怪我,我只是答應了盡力,可沒保證什麼。因此,若是IP包傳輸過程當中出現錯誤(好比checksum對不上,好比交通太繁忙,好比超過Time to Live),根據IP協議,你的IP包會直接被丟掉。Game Over, 不會再有進一步的努力來修正錯誤。Best effort讓IP協議保持很簡單的形態。更多的質量控制交給高層協議處理,IP協議只負責有效率的傳輸。
(多麼不負責任的郵遞系統)
「效率優先」也體如今IP包的順序(order)上。即便出發地和目的地保持不變,IP協議也不保證IP包到達的前後順序。咱們已經知道,IP接力是根據routing table決定接力路線的。若是在連續的IP包發送過程當中,routing table更新(好比有一條新建的捷徑出現),那麼後發出的IP包選擇走不同的接力路線。若是新的路徑傳輸速度更快,那麼後發出的IP包有可能先到。這就好像是多車道的公路上,每輛車都在不停變換車道,最終全部的車道都塞滿汽車。這樣可讓公路利用率達到最大。
「插隊」
IPv6中的Flow Label能夠建議路由器將一些IP包保持同樣的接力路徑。但這只是「建議」,路由器可能會忽略該建議。
Header Checksum區域有16位。它是這樣得到的,從header取得除checksum以外的0/1序列,好比:
9194 8073 0000 4000 4011 C0A8 0001 C0A8 00C7 (十六進制hex, 這是一個爲演示運算過程而設計的header)
按照十六位(也就是4位hex)分割整個序列。將分割後的各個4位hex累積相加。若是有超過16位的進位出現,則將進位加到後16位結果的最後一位:
Binary Hex
1001000110010100 9194
+ 1000000001110011 8073
----------------
1 0001001000000111 11207
+ 1
----------------
0001001000001000 1208
上面的計算叫作one's complement sum。求得全部十六位數的和,
one's complement sum(4500, 0073, 0000, 4000, 4011, C0A8, 0001, C0A8, 00C7) = 1433
而後,將1433的每一位取反(0->1, 1->0), 就獲得checksum:EBCC
這樣,咱們的header就是:
9194 8073 0000 4000 4011 EBCC C0A8 0001 C0A8 00C7
IP包的接收方在接收到IP包以後,能夠求上面各個16位數的one's complement sum,應該獲得FFFF。若是不是FFFF,那麼header是不正確的,整個IP包會被丟棄。
(再次提醒,示例所用的IP header不是真實的header,它只是起演示算法的做用)
每一個網絡協議的造成都有其歷史緣由。好比IP協議是爲了將各個分散的實驗室網絡鏈接起來。因爲當時的網絡很小,因此IPv4(IPv4產生與70年代)的地址總量爲40億。儘管當時被認爲是很大的數字,但數字浪潮很快帶來了地址耗盡危機。IPv6的主要目的是增長IPv4的地址容量,但同時根據IPv4的經驗和新時代的技術進步進行改進,好比避免碎片化,好比取消checksum (因爲高層協議TCP的普遍使用)。網絡協議技術上並不複雜,更多的考量是政策性的。
IP協議是"Best Effort"式的,IP傳輸是不可靠的。但這樣的設計成就了IP協議的效率。