TCP/IP網(wǎng)絡(luò)模型入門
TCP/IP網(wǎng)絡(luò)模型
TCP/IP模型是互聯(lián)網(wǎng)的基礎(chǔ),它是一系列網(wǎng)絡(luò)協(xié)議的總稱。這些協(xié)議可以劃分為四層,分別為鏈路層、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。
- 鏈路層:負(fù)責(zé)封裝和解封裝IP報(bào)文,發(fā)送和接受ARP/RARP報(bào)文等。
- 網(wǎng)絡(luò)層:負(fù)責(zé)路由以及把分組報(bào)文發(fā)送給目標(biāo)網(wǎng)絡(luò)或主機(jī)。
- 傳輸層:負(fù)責(zé)對(duì)報(bào)文進(jìn)行分組和重組,并以TCP或UDP協(xié)議格式封裝報(bào)文。
- 應(yīng)用層:負(fù)責(zé)向用戶提供應(yīng)用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。
在網(wǎng)絡(luò)體系結(jié)構(gòu)中網(wǎng)絡(luò)通信的建立必須是在通信雙方的對(duì)等層進(jìn)行,不能交錯(cuò)。 在整個(gè)數(shù)據(jù)傳輸過(guò)程中,數(shù)據(jù)在發(fā)送端時(shí)經(jīng)過(guò)各層時(shí)都要附加上相應(yīng)層的協(xié)議頭和協(xié)議尾(僅數(shù)據(jù)鏈路層需要封裝協(xié)議尾)部分,也就是要對(duì)數(shù)據(jù)進(jìn)行協(xié)議封裝,以標(biāo)識(shí)對(duì)應(yīng)層所用的通信協(xié)議。
OSI七層模型
當(dāng)然在理論上,還有一個(gè)OSI七層模型:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層和應(yīng)用層。這是一個(gè)理想模型,由于其復(fù)雜性并沒(méi)有被大家廣泛采用。
鏈路層
(1) 以太網(wǎng)和802封裝
以太網(wǎng)封裝是以RFC894定義的 而802封裝則是RFC1042定義的 主機(jī)需求RFC要求: (1)必須支持以太網(wǎng)封裝 (2)應(yīng)該支持與RFC894混合的RFC1042封裝 (3)或許可以發(fā)送RFC1042封裝的分組
(2) SLIP
適用于RS-232和高速調(diào)制解調(diào)器接入網(wǎng)絡(luò) (1)以0xC0結(jié)束 (2)對(duì)報(bào)文中的0xC0和ESC字符進(jìn)行轉(zhuǎn)義 缺點(diǎn):沒(méi)有辦法通知本端IP到對(duì)端;沒(méi)有類型字段;沒(méi)有校驗(yàn)和
(3) CSLIP
將SLIP報(bào)文中的20字節(jié)IP首部和20字節(jié)TCP首部壓縮為3或5字節(jié)
(4) PPP協(xié)議
修正了SLIP協(xié)議的缺陷,支持多種協(xié)議類型;帶數(shù)據(jù)校驗(yàn)和;報(bào)文首部壓縮;雙方可以進(jìn)行IP地址動(dòng)態(tài)協(xié)商(使用IP協(xié)議);鏈路控制協(xié)議可以對(duì)多個(gè)鏈路選項(xiàng)進(jìn)行設(shè)置。
(5) 環(huán)回接口
用于同一臺(tái)主機(jī)上的程序通過(guò)TCP/IP通信。 傳給環(huán)回的數(shù)據(jù)均作為輸入; 傳給該主機(jī)IP地址的數(shù)據(jù)也是送到環(huán)回接口; 廣播和多播數(shù)據(jù)先復(fù)制一份到環(huán)回接口,再送到以太網(wǎng)上。
(6) MTU
對(duì)數(shù)據(jù)幀長(zhǎng)度的***限制,如果數(shù)據(jù)分組長(zhǎng)度大于這個(gè)數(shù)值,需要在IP層對(duì)其分片。 注意:發(fā)往以太網(wǎng)的數(shù)據(jù)要考慮路徑MTU
IP網(wǎng)際協(xié)議
IP是TCP/IP中最為核心的協(xié)議,所有的TCP、UDP、ICMP等協(xié)議均以IP數(shù)據(jù)報(bào)的格式傳輸。IP協(xié)議提供不可靠、無(wú)連接的服務(wù),它不保證數(shù)據(jù)報(bào)一定可以送達(dá)目的,也不保證數(shù)據(jù)報(bào)的先后次序。
IP首部格式為:
注:網(wǎng)絡(luò)字節(jié)序:32bit傳輸?shù)拇涡驗(yàn)?-7bit, 8-15bit, 16-23bit, 24-31bit(即big endian字節(jié)序)
IP路由
IP路由選擇是逐跳進(jìn)行的。IP并不知道到達(dá)任何目的的完整路徑(當(dāng)然,除了那些與主機(jī)直接相連的)。所有的IP路由選擇只為數(shù)據(jù)報(bào)傳輸提供下一站路由器的I P地址。它假定下一站路由器比發(fā)送數(shù)據(jù)報(bào)的主機(jī)更接近目的,而且下一站路由器與該主機(jī)是直接相連的。
IP路由選擇主要完成以下這些功能:
- 搜索路由表,尋找能與目的IP地址完全匹配的表目(網(wǎng)絡(luò)號(hào)和主機(jī)號(hào)都要匹配)。如果找到,則把報(bào)文發(fā)送給該表目指定的下一站路由器或直接連接的網(wǎng)絡(luò)接口(取決于標(biāo)志字段的值)。
- 搜索路由表,尋找能與目的網(wǎng)絡(luò)號(hào)相匹配的表目。如果找到,則把報(bào)文發(fā)送給該表目指定的下一站路由器或直接連接的網(wǎng)絡(luò)接口(取決于標(biāo)志字段的值)。目的網(wǎng)絡(luò)上的所有主機(jī)都可以通過(guò)這個(gè)表目來(lái)處置。例如,一個(gè)以太網(wǎng)上的所有主機(jī)都是通過(guò)這種表目進(jìn)行尋徑的。這種搜索網(wǎng)絡(luò)的匹配方法必須考慮可能的子網(wǎng)掩碼。關(guān)于這一點(diǎn)我們?cè)谙乱还?jié)中進(jìn)行討論。
- 搜索路由表,尋找標(biāo)為“默認(rèn)”的表目。如果找到,則把報(bào)文發(fā)送給該表目指定的下一站路由器。
如果上面這些步驟都沒(méi)有成功,那么該數(shù)據(jù)報(bào)就不能被傳送。如果不能傳送的數(shù)據(jù)報(bào)來(lái)自本機(jī),那么一般會(huì)向生成數(shù)據(jù)報(bào)的應(yīng)用程序返回一個(gè)“主機(jī)不可達(dá)”或“網(wǎng)絡(luò)不可達(dá)”的錯(cuò)誤。
IP路由選擇是通過(guò)逐跳來(lái)實(shí)現(xiàn)的。數(shù)據(jù)報(bào)在各站的傳輸過(guò)程中目的IP地址始終不變,但是封裝和目的鏈路層地址在每一站都可以改變。大多數(shù)的主機(jī)和許多路由器對(duì)于非本地網(wǎng)絡(luò)的數(shù)據(jù)報(bào)都使用默認(rèn)的下一站路由器。
IP路由選擇機(jī)制的兩個(gè)特征: (1)完整主機(jī)地址匹配在網(wǎng)絡(luò)號(hào)匹配之前執(zhí)行 (2)為網(wǎng)絡(luò)指定路由,而不必為每個(gè)主機(jī)指定路由
IP地址和MAC地址分類
按IP地址范圍劃分:
- A類:地址范圍1.0.0.1-126.255.255.25***類IP地址的子網(wǎng)掩碼為255.0.0.0,每個(gè)網(wǎng)絡(luò)支持的***主機(jī)數(shù)為256的3次方-2=16777214臺(tái)。
- B類:地址范圍128.0.0.1-191.255.255.255,B類IP地址的子網(wǎng)掩碼為255.255.0.0,每個(gè)網(wǎng)絡(luò)支持的***主機(jī)數(shù)為256的2次方-2=65534臺(tái)
- C類:地址范圍192.0.1.1-223.255.255.255,C類IP地址的子網(wǎng)掩碼為255.255.255.0,每個(gè)網(wǎng)絡(luò)支持的***主機(jī)數(shù)為256-2=254臺(tái)
- D類:以1110開始的地址,多播地址
- E類:以11110開始的地址,保留地址
按照通訊模式劃分:
- 單播:目標(biāo)是特定的主機(jī),比如192.168.0.3
- 廣播:目標(biāo)IP地址的主機(jī)部分全為1,并且目的MAC地址為FF-FF-FF-FF-FF-FF。比如B類網(wǎng)絡(luò)172.16.0.0的默認(rèn)子網(wǎng)掩碼為255.255.0.0,廣播地址為172.16.255.255。
- 多播:目標(biāo)為一組主機(jī),IP地址范圍為224.0.0.0~239.255.255.255。多播MAC地址以十六進(jìn)制值01-00-5E打頭,余下的6個(gè)十六進(jìn)制位根據(jù)IP多播組地址的***23位轉(zhuǎn)換得到。
單播是對(duì)特定的主機(jī)進(jìn)行數(shù)據(jù)傳送。如給某一個(gè)主機(jī)發(fā)送IP數(shù)據(jù)包,鏈路層頭部是非常具體的目的地址,對(duì)于以太網(wǎng)來(lái) 說(shuō),就是網(wǎng)卡的MAC地址。廣播和多播僅應(yīng)用于UDP,它們對(duì)需將報(bào)文同時(shí)傳往多個(gè)接收者的應(yīng)用來(lái)說(shuō)十分重要。
- 廣播是針對(duì)某一個(gè)網(wǎng)絡(luò)上的所有主機(jī)發(fā)包,這個(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)核就可以了。一般說(shuō)來(lái)ARP,或者路由協(xié)議RIP應(yīng)該是以廣播的形式播發(fā)的。
- 多播就是給一組特定的主機(jī)(多播組)發(fā)送數(shù)據(jù),這樣,數(shù)據(jù)的播發(fā)范圍會(huì)小一些。多播的MAC地址是***字節(jié)的低位為一,例 如01-00-00-00-00-00。多播組的地址是D類IP,規(guī)定是224.0.0.0-239.255.255.255。與IP多播相對(duì)應(yīng)的以太網(wǎng)地址范圍從0 1 : 0 0 : 5 e : 0 0 : 0 0 : 0 0到01: 00: 5e: 7f: ff: ff。通過(guò)將其低位23 bit映射到相應(yīng)以太網(wǎng)地址中便可實(shí)現(xiàn)多播組地址到以太網(wǎng)地址的轉(zhuǎn)換。由于地址映射是不唯一的,因此要其他的協(xié)議實(shí)現(xiàn)額外的數(shù)據(jù)報(bào)過(guò)濾。
子網(wǎng)掩碼
子網(wǎng)掩碼用來(lái)確定多少bit用于網(wǎng)絡(luò)號(hào)和多少bit用于主機(jī)號(hào)。
給定IP地址和子網(wǎng)掩碼以后,主機(jī)就可以確定IP數(shù)據(jù)報(bào)的目的是: (1)本子網(wǎng)上的主機(jī); (2)本網(wǎng)絡(luò)中其他子網(wǎng)中的主機(jī); (3)其他網(wǎng)絡(luò)上的主機(jī)。
如果知道本機(jī)的IP地址,那么就知道它是否為A類、B類或C類地址(從IP地址的高位可以得知),也就知道網(wǎng)絡(luò)號(hào)和子網(wǎng)號(hào)之間的分界線。而根據(jù)子網(wǎng)掩碼就可知道子網(wǎng)號(hào)與主機(jī)號(hào)之間的分界線。
封裝
以太網(wǎng)數(shù)據(jù)幀的物理特性是其長(zhǎng)度必須在46~1500字節(jié)之間,而數(shù)據(jù)幀在進(jìn)入每一層協(xié)議棧的時(shí)候均會(huì)做一些封裝。
而更具體的以太網(wǎng)幀格式為:
分用
當(dāng)目的主機(jī)收到一個(gè)以太網(wǎng)幀時(shí),就在協(xié)議棧中從底向上升,同時(shí)去掉各層協(xié)議加上的報(bào)文首部。每層協(xié)議盒都要去檢查報(bào)文首部的協(xié)議標(biāo)識(shí),以確定接收數(shù)據(jù)的上層協(xié)議。這個(gè)過(guò)程稱作分用。
分段 (fragmentation)
老的內(nèi)核通常在IP層處理IP分段,IP層可以接收0~64KB的數(shù)據(jù)。因此,當(dāng)數(shù)據(jù)IP packet大于PMTU時(shí),就必須把數(shù)據(jù)分成多個(gè)IP分段。 較新的內(nèi)核中,L4會(huì)嘗試進(jìn)行分段:L4不會(huì)再把超過(guò)PMTU的緩沖區(qū)直接傳給IP層,而是傳遞一組和PMTU相匹配的緩沖區(qū)。這樣,IP層只需要給每個(gè)分段增加IP報(bào)頭。但是這并不意味著IP層就不做分段的工作了,一些情況下,IP層還會(huì)進(jìn)行分段操作。
- 分段是指將一個(gè)IP包分成多個(gè)傳輸,在接收端 IP 層重新組裝
- 一個(gè) IP 包能否分包,取決于它的 DF 標(biāo)志位:DF bit (0 = "may fragment," 1 = "don't fragment")
- 分包后,每個(gè)分段有 MF 標(biāo)志位:MF bit (0 = "last fragment," 1 = "more fragments")
***個(gè)表格中:
- IP 包長(zhǎng)度 5140,包括 5120 bytes 的 payload
- DF = 0, 允許分包
- MF = 0, 這是未分包
第二個(gè)表格中:
- 0-0 ***個(gè)分包: 長(zhǎng)度 1500 = 1480 (payload) + 20 (IP Header). Offset(起始偏移量): 0
- 0-1 第二個(gè)分包: 長(zhǎng)度 1500 = 1480 (payload) + 20 (IP Header). Offset: 185 = 1480 / 8
- 0-2 第三個(gè)分包: 長(zhǎng)度 1500 = 1480 (payload) + 20 (IP Header). Offset: 370 = 185 + 1480/8
- 0-3 第四個(gè)分包: 長(zhǎng)度 700 = 680 (payload, = (5140 - 20) - 1480 * 3) + 20 (IP Header) . Offset: 555 = 370 + 1480/8
需要注意的是,只有***個(gè)包帶有原始包的完整 IPv4 + TCP/UDP 信息,后續(xù)的分包只有 IPv4 信息。
分包帶來(lái)的問(wèn)題:
- sender overhead:需要消耗 CPU 去分包,包括計(jì)算和數(shù)據(jù)拷貝。
- receiver overhead:重新組裝多個(gè)分包。在路由器上組裝非常低效率,因此組裝往往在接收主機(jī)上進(jìn)行。
- 重發(fā) overhead:一個(gè)分包丟失,則整個(gè)包需要重傳。
- 在多個(gè)分包出現(xiàn)順序錯(cuò)開時(shí),防火墻可能將分到當(dāng)無(wú)效包處理而丟棄。
MTU
一個(gè)網(wǎng)絡(luò)接口的 MTU 是它一次所能傳輸?shù)?**數(shù)據(jù)塊的大小。任何超過(guò)MTU的數(shù)據(jù)塊都會(huì)在傳輸前分成小的傳輸單元。MTU 有兩個(gè)測(cè)量層次:網(wǎng)絡(luò)層和鏈路層。比如,網(wǎng)絡(luò)層上標(biāo)準(zhǔn)的因特網(wǎng) MTU 是 1500 bytes,而在連接層上是 1518 字節(jié)。沒(méi)有特別說(shuō)的時(shí)候,往往指的是網(wǎng)絡(luò)層的MTU。
要增加一個(gè)網(wǎng)絡(luò)接口 MTU 的常見(jiàn)原因是增加高速因特網(wǎng)的吞吐量。標(biāo)準(zhǔn)因特網(wǎng) MTU 使用 1500byte是為了和 10M 和 100M 網(wǎng)絡(luò)后向兼容,但是,在目前1G和 10G網(wǎng)絡(luò)中遠(yuǎn)遠(yuǎn)不夠。新式的網(wǎng)絡(luò)設(shè)備可以處理更大的MTU,但是,MTU需要顯式設(shè)置。這種更大MTU的幀叫做“巨幀”,通常 9000 byte 是比較普遍的。
相對(duì)地,一些可能得需要減少M(fèi)TU的原因:
- 滿足另一個(gè)網(wǎng)絡(luò)的MTU的需要(為了消除UDP分包,以及需要TCP PMTU discover )
- 滿足 ATM cell 的要求
- 在高出錯(cuò)率線路上提高吞吐量
MTU 不能和目前任何 Internet 網(wǎng)絡(luò)協(xié)議混在一起,但是,可以使用一個(gè)路由器將不同 MTU 的網(wǎng)段連在一起。
TCP fragmentation
每個(gè)TCP數(shù)據(jù)包(segment)的大小受MSS(TCP_MAXSEG選項(xiàng))限制。***報(bào)文段長(zhǎng)度 ( MSS )表示 TCP 傳往另一端的***塊數(shù)據(jù)的長(zhǎng)度。當(dāng)一個(gè)連接建立時(shí)(SYN packet), 連接的雙方都要通告各自的MSS。
一般說(shuō)來(lái),如果沒(méi)有分段發(fā)生, MSS還是越大越好。報(bào)文段越大允許每個(gè)報(bào)文段傳送的數(shù)據(jù)就越多,相對(duì)IP和TCP首部有更高的網(wǎng)絡(luò)利用率。當(dāng)TCP發(fā)送一個(gè)SYN時(shí),或者是因?yàn)橐粋€(gè)本地應(yīng)用進(jìn)程想發(fā)起一個(gè)連接,或者是因?yàn)榱硪欢说闹鳈C(jī)收到了一個(gè)連接請(qǐng)求,它能將MSS值設(shè)置為外出接口上的MTU長(zhǎng)度減去固定的IP首部(20 bytes)和TCP首部長(zhǎng)度(20 bytes)。對(duì)于一個(gè)以太網(wǎng),MSS值可達(dá)1460字節(jié)(詳細(xì)參考tcp_sendmsg)。
TCP/SCTP會(huì)將數(shù)據(jù)按MTU進(jìn)行切片,然后3層的工作只需要給傳遞下來(lái)的切片加上 ip頭就可以了(也就是說(shuō)調(diào)用這個(gè)函數(shù)的時(shí)候,其實(shí)4層已經(jīng)切好片了)。
Segmentation offload
現(xiàn)在很多網(wǎng)卡本身支持?jǐn)?shù)據(jù)分片,這樣,上層L4/L3就可以不用進(jìn)行分片(***64KB),而由NIC來(lái)完成,從而提高網(wǎng)絡(luò)性能。
- Large Segment Offload (LSO):使得網(wǎng)絡(luò)協(xié)議棧能夠?qū)⒊^(guò)PMTU的數(shù)據(jù)包推送至網(wǎng)卡,然后網(wǎng)卡執(zhí)行分片工作,這樣減輕了CPU的負(fù)荷
- TCP Segmentation Offload (TSO):類似于LSO,針對(duì)TCP協(xié)議包
- UDP Fragmentation Offload (UFO): 類似于TSO,針對(duì)UDP包
- Large Receive Offload (LRO): 將接收到的包聚合成一個(gè)大的數(shù)據(jù)包,然后再發(fā)給協(xié)議棧處理
- Generic Segmentation Offload (GSO): TSO/LSO的增強(qiáng),同時(shí)支持TCP和UDP協(xié)議,負(fù)責(zé)把超過(guò)MTU的包分片
- Generic Receive Offload (GRO):LRO的增強(qiáng),負(fù)責(zé)將接收到的多個(gè)包聚合成一個(gè)大的數(shù)據(jù)包,然后再發(fā)給協(xié)議棧處理
PMTU (Path Maximum Transmission Unit Discovery)
PMTU 的用途是動(dòng)態(tài)的確定從發(fā)送端到接收端整個(gè)路徑上的最小 MTU,從而避免分包。注意,PMTU 只支持 TCP,對(duì)其他協(xié)議比如 UDP 無(wú)效。而且,如果發(fā)送方已經(jīng)開啟了 PMTU,那么它發(fā)送的所有 TCP/IP 包的 DF 標(biāo)志都被設(shè)置為 1 即不再允許分包。當(dāng)網(wǎng)絡(luò)路徑上某個(gè)路由器發(fā)現(xiàn)發(fā)送者的包因?yàn)槌^(guò)前面轉(zhuǎn)發(fā)路徑的 MTU 而無(wú)法發(fā)送時(shí),它向發(fā)送者返回一個(gè) ICMP "Destination Unreachable" 消息,其中包含了那個(gè) MTU,然后發(fā)送者就會(huì)在它的路由表中將該mtu值保存下來(lái),再使用較小的 MTU 重新發(fā)出新的較小的包。
例子1:超過(guò) MTU,DF = 0 => 路由器分包、發(fā)送,接收主機(jī)組裝
例子2:超過(guò),DF = 1 => PMTU,發(fā)送者重新以小包發(fā)送
