謝崗做網(wǎng)站上海網(wǎng)站搜索引擎優(yōu)化
文章目錄
- 4.傳輸層重點(diǎn)協(xié)議
- 4.1TCP協(xié)議
- 4.1.1TCP協(xié)議段格式
- 4.1.2TCP原理
- 4.1.2.1確認(rèn)應(yīng)答機(jī)制 ACK(安全機(jī)制)
- 4.1.2.2超時(shí)重傳機(jī)制(安全機(jī)制)
- 4.1.2.3連接管理機(jī)制(安全機(jī)制)
- 4.1.2.4滑動(dòng)窗口(效率機(jī)制)
- 4.1.2.5流量控制(安全機(jī)制)- 接收方
- 4.1.2.6擁塞控制(安全機(jī)制)- 中間節(jié)點(diǎn)過(guò)程
- 4.1.2.7延遲應(yīng)答(效率機(jī)制)
- 4.1.2.8捎帶應(yīng)答(效率機(jī)制)
- 4.1.3粘包問(wèn)題
- 4.1.4TCP異常情況
- 4.1.5TCP小結(jié)
- 4.1.6基于TCP應(yīng)用層協(xié)議
- 4.2UDP協(xié)議
- 4.2.1UDP協(xié)議端格式
- 4.2.2UDP的特點(diǎn)
- 4.2.3基于UDP的應(yīng)用層協(xié)議
- 4.2.4擴(kuò)展問(wèn)題
- 4.3TCP/UDP對(duì)比
- 5.網(wǎng)絡(luò)層重點(diǎn)協(xié)議
- 5.1IP協(xié)議
- 6.數(shù)據(jù)鏈路層重點(diǎn)協(xié)議
- 6.1認(rèn)識(shí)以太網(wǎng)
- 6.1.1以太網(wǎng)幀格式
- 6.1.2 IP地址 和 mac地址有啥區(qū)別嗎?
- 6.2認(rèn)識(shí)MTU(對(duì)于較大的IP數(shù)據(jù)包要進(jìn)行分包)
- 6.2.1MTU對(duì)IP協(xié)議的影響
- 6.2.2MTU對(duì)UDP協(xié)議的影響
- 6.2.3MTU對(duì)于TCP協(xié)議的影響
- 6.3ARP協(xié)議
- 6.3.1ARP協(xié)議的作用(直到 ip 通過(guò) ARP 來(lái)返回 mac)
- 6.3.2ARP協(xié)議的工作流程
- 7.總結(jié)
- 7.1數(shù)據(jù)鏈路層
- 7.2網(wǎng)絡(luò)層
- 7.3傳輸層
- 7.4應(yīng)用層
大家好,我是曉星航。今天為大家?guī)?lái)的是 網(wǎng)絡(luò)原理之TCP_IP 相關(guān)的講解!😀
4.傳輸層重點(diǎn)協(xié)議
負(fù)責(zé)數(shù)據(jù)能夠從發(fā)送端傳輸接收端。
4.1TCP協(xié)議
TCP,即Transmission Control Protocol,傳輸控制協(xié)議。人如其名,要對(duì)數(shù)據(jù)的傳輸進(jìn)行一個(gè)詳細(xì)的控制。
4.1.1TCP協(xié)議段格式
- 源/目的端口號(hào):表示數(shù)據(jù)是從哪個(gè)進(jìn)程來(lái),到哪個(gè)進(jìn)程去;
- 32位序號(hào)/32位確認(rèn)號(hào):后面詳細(xì)講;
- 4位TCP報(bào)頭長(zhǎng)度:表示該TCP頭部有多少個(gè)32位bit(有多少個(gè)4字節(jié));首部長(zhǎng)度的單位是4字節(jié)而不是字節(jié)。如果首部長(zhǎng)度是15,那么TCP頭部最大長(zhǎng)度是 15 * 4 = 60 (長(zhǎng)度是可變的) 后面的6位為保留位,可以類比于保留字。
- 6位標(biāo)志位:
- URG:緊急指針是否有效
- ACK:確認(rèn)號(hào)是否有效
- PSH:提示接收端應(yīng)用程序立刻從TCP緩沖區(qū)把數(shù)據(jù)讀走
- RST:對(duì)方要求重新建立連接;我們把攜帶RST標(biāo)識(shí)的稱為復(fù)位報(bào)文段
- SYN:請(qǐng)求建立連接;我們把攜帶SYN標(biāo)識(shí)的稱為同步報(bào)文段
- FIN:通知對(duì)方,本端要關(guān)閉了,我們稱攜帶FIN標(biāo)識(shí)的為結(jié)束報(bào)文段
- 16位窗口大小:后面再說(shuō)
- 16位校驗(yàn)和:發(fā)送端填充,CRC校驗(yàn)。接收端校驗(yàn)不通過(guò),則認(rèn)為數(shù)據(jù)有問(wèn)題。此處的檢驗(yàn)和不光 包含TCP首部,也包含TCP數(shù)據(jù)部分。
- 16位緊急指針:標(biāo)識(shí)哪部分?jǐn)?shù)據(jù)是緊急數(shù)據(jù);
- 40字節(jié)頭部選項(xiàng)(option):此處的選項(xiàng)相當(dāng)于對(duì)這個(gè) TCP 報(bào)文的一些屬性進(jìn)行解釋說(shuō)明的(可有可無(wú))。
4.1.2TCP原理
TCP對(duì)數(shù)據(jù)傳輸提供的管控機(jī)制,主要體現(xiàn)在兩個(gè)方面:安全和效率。
這些機(jī)制和多線程的設(shè)計(jì)原則類似:保證數(shù)據(jù)傳輸安全的前提下,盡可能的提高傳輸效率。
4.1.2.1確認(rèn)應(yīng)答機(jī)制 ACK(安全機(jī)制)
A 給 B 發(fā)了個(gè)信息,B 收到之后就會(huì)返回一個(gè) 應(yīng)答報(bào)文(ACK) — answer,此時(shí) A 收到應(yīng)答之后,就知道了剛才發(fā)的數(shù)據(jù)已經(jīng)順利到達(dá) B 了。
[唐僧講經(jīng)例子]
TCP將每個(gè)字節(jié)的數(shù)據(jù)都進(jìn)行了編號(hào),按照字節(jié)來(lái)編號(hào)的。即為序列號(hào)。
每一個(gè)ACK都帶有對(duì)應(yīng)的確認(rèn)序列號(hào),意思是告訴發(fā)送者,我已經(jīng)收到了哪些數(shù)據(jù);下一次你從哪里開(kāi)始發(fā)。(通過(guò)引入 序號(hào)
和 確認(rèn)序號(hào)
來(lái)區(qū)分當(dāng)前應(yīng)答報(bào)文是針對(duì)那個(gè)數(shù)據(jù)進(jìn)行的了)
例如,主機(jī)A發(fā)送的當(dāng)前數(shù)據(jù)序號(hào)是400,數(shù)據(jù)長(zhǎng)度是100,則接收端收到后會(huì)返回一個(gè)確認(rèn)號(hào)是501的確認(rèn)號(hào)給主機(jī)A。
確認(rèn)序號(hào)的取值,是收到的數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào) + 1.
表示的含義:
例如如果此時(shí)確認(rèn)序號(hào)是 1001
- < 1001 的數(shù)據(jù)都已經(jīng)確認(rèn)收到了!
- A 接下來(lái)應(yīng)該從 1001 這個(gè)序號(hào)開(kāi)始繼續(xù)發(fā)送。 ( B向A索要 1001 的數(shù)據(jù) )
如果我們要找1 - 1000 的報(bào)頭,此時(shí)1 - 1000 都是屬于一個(gè) TCP 數(shù)據(jù)包的,所以他的報(bào)頭只需要填 1 就行了。
同理,1001 - 2000 的報(bào)頭就是 1001。
2001 - 3000 的包頭就是 2001。
TCP進(jìn)行可靠性傳輸,最主要就是靠這個(gè)確認(rèn)應(yīng)答機(jī)制。
4.1.2.2超時(shí)重傳機(jī)制(安全機(jī)制)
丟包可能是數(shù)據(jù)丟包
- 主機(jī) A發(fā)送數(shù)據(jù)給 B之后,可能因?yàn)榫W(wǎng)絡(luò)擁堵等原因,數(shù)據(jù)無(wú)法到達(dá)主機(jī) B;
- 如果主機(jī)A在一個(gè)特定時(shí)間間隔內(nèi)沒(méi)有收到 B發(fā)來(lái)的確認(rèn)應(yīng)答,就會(huì)進(jìn)行重發(fā);
但是,主機(jī)A未收到B發(fā)來(lái)的確認(rèn)應(yīng)答,也可能是因?yàn)锳CK丟失了;
因?yàn)槲覀償?shù)據(jù)丟包了,因此我們就會(huì)進(jìn)行重新傳輸來(lái)應(yīng)對(duì)這一丟包問(wèn)題。
因此主機(jī)B會(huì)收到很多重復(fù)數(shù)據(jù)。那么TCP協(xié)議需要能夠識(shí)別出那些包是重復(fù)的包,并且把重復(fù)的丟棄掉。
這時(shí)候我們可以利用前面提到的序列號(hào),就可以很容易做到去重的效果。
那么,如果超時(shí)的時(shí)間如何確定?
- 最理想的情況下,找到一個(gè)最小的時(shí)間,保證 “確認(rèn)應(yīng)答一定能在這個(gè)時(shí)間內(nèi)返回”。
- 但是這個(gè)時(shí)間的長(zhǎng)短,隨著網(wǎng)絡(luò)環(huán)境的不同,是有差異的。
- 如果超時(shí)時(shí)間設(shè)的太長(zhǎng),會(huì)影響整體的重傳效率;
- 如果超時(shí)時(shí)間設(shè)的太短,有可能會(huì)頻繁發(fā)送重復(fù)的包;
TCP為了保證無(wú)論在任何環(huán)境下都能比較高性能的通信,因此會(huì)動(dòng)態(tài)計(jì)算這個(gè)最大超時(shí)時(shí)間。
- Linux中(BSD Unix和Windows也是如此),超時(shí)以500ms為一個(gè)單位進(jìn)行控制,每次判定 超時(shí)重發(fā)的超時(shí)時(shí)間都是500ms的整數(shù)倍。
- 如果重發(fā)一次之后,仍然得不到應(yīng)答,等待 2*500ms 后再進(jìn)行重傳。
- 如果仍然得不到應(yīng)答,等待 4*500ms 進(jìn)行重傳。依次類推,以指數(shù)形式遞增。
- 累計(jì)到一定的重傳次數(shù),TCP認(rèn)為網(wǎng)絡(luò)或者對(duì)端主機(jī)出現(xiàn)異常,強(qiáng)制關(guān)閉連接。
4.1.2.3連接管理機(jī)制(安全機(jī)制)
在正常情況下,TCP要經(jīng)過(guò)三次握手建立連接,四次揮手?jǐn)嚅_(kāi)連接
三次握手:
SYN(synchronize):客戶端主動(dòng)給服務(wù)器發(fā)起的建立連接請(qǐng)求,稱為"SYN",同步報(bào)文段。 這里的同步在我們圖上理解就是創(chuàng)建連接的意思,只不過(guò)這里我們把他稱作為同步。
ACK:應(yīng)答報(bào)文。
上述粉框框住的地方是我們 TCP 的狀態(tài)。
三次握手,建立連接階段,主要認(rèn)識(shí)兩個(gè)狀態(tài):
- LISTEN 服務(wù)器狀態(tài)。
表示服務(wù)器已經(jīng)準(zhǔn)備就緒,隨時(shí)可以有客戶端來(lái)建立連接了。相當(dāng)于 手機(jī)開(kāi)機(jī),信號(hào)良好,隨時(shí)可以有人來(lái)打電話了 - ESTABLISHED 客戶端和服務(wù)器都有
連接建立完成,接下來(lái)就可以正常通信了。
相當(dāng)于電話撥打過(guò)去,對(duì)方接通了。
藍(lán)框里面描述了 TCP 和 socket api 之間的關(guān)系。此處的 socket api 是系統(tǒng)原生api(C 語(yǔ)言版本的),這個(gè)和 Java 版本的已經(jīng)有一定差距了。
所謂的三次握手,本質(zhì)上是"四次"交互。 — 通信雙方,各自要向?qū)Ψ桨l(fā)起一個(gè) “建立連接的請(qǐng)求”。同時(shí),再各自向?qū)Ψ交貞?yīng)一個(gè) ack ,共四次。但是中間兩次交互,是可以合并成一次交互的。因此就構(gòu)成了"三次握手"。
那么問(wèn)題來(lái)了,為什么要把中間兩次合并?不合并行不行?
答:必須合并!!!因?yàn)檫@里涉及到封裝分用,封裝分用兩次比封裝分用一次成本更高。
三次握手另外一個(gè)重要的作用:驗(yàn)證同行雙方各自的發(fā)送能力和接受能力是否正常。
三次握手的意義:
- 讓通信雙方各自建立對(duì)對(duì)方的"認(rèn)同"
- 驗(yàn)證通信雙方各自的發(fā)送能力和接收能力是否 ok。
- 在握手的過(guò)程中,雙方來(lái)協(xié)商一些重要的參數(shù)
如果未來(lái)我們?nèi)ッ嬖?#xff0c;面試官問(wèn)我們什么是三次握手過(guò)程,請(qǐng)你描述一下、
此時(shí)我們最好自帶一套紙筆去面試,再描述三次握手的時(shí)候邊畫(huà)圖邊講解!!!
向上述這樣畫(huà)圖即可,中間一次過(guò)程合并了一次交互!
四次揮手:
四次揮手,關(guān)閉連接階段,主要認(rèn)識(shí)兩個(gè)狀態(tài):
- CLOSE_WAIT 出現(xiàn)在被動(dòng)發(fā)起斷開(kāi)連接的一方
等待關(guān)閉。(等待調(diào)用 close 方法關(guān)閉 socket) - TIME_WAIT 出現(xiàn)在主動(dòng)發(fā)起斷開(kāi)連接的一方
假設(shè)是客戶端主動(dòng)斷開(kāi)連接。當(dāng)客戶端進(jìn)入 TIME_WSIT 狀態(tài)時(shí)候,相當(dāng)于四次揮手已經(jīng)揮完。
此時(shí)這里的 TIME_WAIT 要保持當(dāng)前的 TCP 連接狀態(tài)不要立即就釋放。
注意,在斷開(kāi)連接的過(guò)程中,中間兩次,通常情況下不能合并。(特殊情況下可以)—兩個(gè)數(shù)據(jù)發(fā)送的時(shí)機(jī)相同,才能合并。如果是不同時(shí)機(jī),就合并不了。
三次握手中間兩次可以合并是因?yàn)樗麄z是同一時(shí)機(jī)。具體來(lái)說(shuō),三次握手這三次交互過(guò)程,是純內(nèi)核中完成的。(應(yīng)用程序感知不到,也干預(yù)不了)
服務(wù)器的系統(tǒng)內(nèi)核收到 syn 之后,就會(huì)立即發(fā)送 ack 也會(huì)立即發(fā)送 syn 。
而四次握手里面,FIN 的發(fā)起,不是由內(nèi)核控制的,而是應(yīng)用程序,調(diào)用 socket 的 close 方法 (或者進(jìn)程退出),才會(huì)觸發(fā) FIN。
而ACK 則是由內(nèi)核控制的,是收到 FIN 之后,立即返回 ACK。
因此四次握手中,中間兩次過(guò)程不可直接合并,因?yàn)樗麄冎g會(huì)有一個(gè)時(shí)間差,他們不是同一時(shí)機(jī)發(fā)出的。
如果未來(lái)我們?nèi)ッ嬖?#xff0c;面試官問(wèn)我們什么是四次揮手過(guò)程,請(qǐng)你描述一下、
此時(shí)我們最好自帶一套紙筆去面試,再描述四次揮手的時(shí)候邊畫(huà)圖邊講解!!!
這里的 四次揮手 和上面的 三次握手 ,同樣是存在超時(shí)重傳的。
如果是最后一個(gè)ACK丟包了,站在服務(wù)器的視角來(lái)看,服務(wù)器是不知道是因?yàn)?ACK 丟了,還是自己發(fā)的 FIN 丟了,所以他會(huì)統(tǒng)一視為 FIN 丟了,統(tǒng)一進(jìn)行重傳操作。
既然服務(wù)器可能要重傳 FIN,客戶端就需要能針對(duì)這個(gè)重傳的 FIN 進(jìn)行 ACK 響應(yīng)。很明顯,如果剛才徹底把連接釋放了,這樣的 ACK 就無(wú)法進(jìn)行了。因此使用 TIME_WAIT 狀態(tài)保留一定時(shí)間,就是為了能夠處理最后一個(gè) ACK 丟包的情況,能夠在收到重傳的 FIN 之后,進(jìn)行 ACK 響應(yīng)。
服務(wù)端狀態(tài)轉(zhuǎn)化:
- [CLOSED -> LISTEN] 服務(wù)器端調(diào)用 listen后進(jìn)入LISTEN狀態(tài),等待客戶端連接;
- [LISTEN -> SYN_RCVD] 一旦監(jiān)聽(tīng)到連接請(qǐng)求(同步報(bào)文段),就將該連接放入內(nèi)核等待隊(duì)列 中,并向客戶端發(fā)送SYN確認(rèn)報(bào)文。
- [SYN_RCVD -> ESTABLISHED] 服務(wù)端一旦收到客戶端的確認(rèn)報(bào)文,就進(jìn)入ESTABLISHED狀 態(tài),可以進(jìn)行讀寫(xiě)數(shù)據(jù)了。
- [ESTABLISHED -> CLOSE_WAIT] 當(dāng)客戶端主動(dòng)關(guān)閉連接(調(diào)用close),服務(wù)器會(huì)收到結(jié)束 報(bào)文段,服務(wù)器返回確認(rèn)報(bào)文段并進(jìn)入CLOSE_WAIT;
- [CLOSE_WAIT -> LAST_ACK] 進(jìn)入CLOSE_WAIT后說(shuō)明服務(wù)器準(zhǔn)備關(guān)閉連接(需要處理完之前 的數(shù)據(jù));當(dāng)服務(wù)器真正調(diào)用close關(guān)閉連接時(shí),會(huì)向客戶端發(fā)送 FIN,此時(shí)服務(wù)器進(jìn)入 LAST_ACK狀態(tài),等待最后一個(gè)ACK到來(lái)(這個(gè)ACK是客戶端確認(rèn)收到了 FIN)
- [LAST_ACK -> CLOSED] 服務(wù)器收到了對(duì) FIN的 ACK,徹底關(guān)閉連接。
客戶端狀態(tài)轉(zhuǎn)化:
- [CLOSED -> SYN_SENT] 客戶端調(diào)用 connect,發(fā)送同步報(bào)文段;
- [SYN_SENT -> ESTABLISHED] connect調(diào)用成功,則進(jìn)入ESTABLISHED狀態(tài),開(kāi)始讀寫(xiě)數(shù)據(jù);
- [ESTABLISHED -> FIN_WAIT_1] 客戶端主動(dòng)調(diào)用 close時(shí),向服務(wù)器發(fā)送結(jié)束報(bào)文段,同時(shí)進(jìn) 入 FIN_WAIT_1;
- [FIN_WAIT_1 -> FIN_WAIT_2] 客戶端收到服務(wù)器對(duì)結(jié)束報(bào)文段的確認(rèn),則進(jìn)入 FIN_WAIT_2, 開(kāi)始等待服務(wù)器的結(jié)束報(bào)文段;
- [FIN_WAIT_2 -> TIME_WAIT] 客戶端收到服務(wù)器發(fā)來(lái)的結(jié)束報(bào)文段,進(jìn)入TIME_WAIT,并發(fā)出 LAST_ACK;
- [TIME_WAIT -> CLOSED] 客戶端要等待一個(gè) 2
MSL
(Max Segment Life,報(bào)文最大生存時(shí)間
)的時(shí)間,才會(huì)進(jìn)入 CLOSED狀態(tài)。(這里給兩個(gè) MSL 的原因是因?yàn)槿绻?FIN 丟了,等 FIN 發(fā)出,然后接收再 ACK 正好是在兩個(gè)報(bào)文最大生存時(shí)間以內(nèi) 即 2MSL)MSL(maximum segment lifetime):中文可以譯為 “報(bào)文最大生存時(shí)間”,他是任何報(bào)文在網(wǎng)絡(luò)上存在的最長(zhǎng)時(shí)間,超過(guò)這個(gè)時(shí)間報(bào)文將被丟棄。
下圖是TCP狀態(tài)轉(zhuǎn)換的一個(gè)匯總:
- 較粗的虛線表示服務(wù)端的狀態(tài)變化情況;
- 較粗的實(shí)線表示客戶端的狀態(tài)變化情況;
- CLOSED是一個(gè)假想的起始點(diǎn),不是真實(shí)狀態(tài);
關(guān)于 “半關(guān)閉” ,男女朋友分手例子
關(guān)于CLOSING狀態(tài)。
TIME_WAIT
想一想,為什么是TIME_WAIT的時(shí)間是2MSL?
- MSL是TCP報(bào)文的最大生存時(shí)間,因此TIME_WAIT持續(xù)存在2MSL的話
- 就能保證在兩個(gè)傳輸方向上的尚未被接收或遲到的報(bào)文段都已經(jīng)消失(否則服務(wù)器立刻重啟,可能會(huì)收到來(lái)自上一個(gè)進(jìn)程的遲到的數(shù)據(jù),但是這種數(shù)據(jù)很可能是錯(cuò)誤的);
- 同時(shí)也是在理論上保證最后一個(gè)報(bào)文可靠到達(dá)(假設(shè)最后一個(gè)ACK丟失,那么服務(wù)器會(huì)再重 發(fā)一個(gè)FIN。這時(shí)雖然客戶端的進(jìn)程不在了,但是TCP連接還在,仍然可以重發(fā) LAST_ACK);
CLOSE_WAIT
一般而言,對(duì)于服務(wù)器上出現(xiàn)大量的 CLOSE_WAIT 狀態(tài),原因就是服務(wù)器沒(méi)有正確的關(guān)閉 socket,導(dǎo) 致四次揮手沒(méi)有正確完成。這是一個(gè) BUG。只需要加上對(duì)應(yīng)的 close 即可解決問(wèn)題。
4.1.2.4滑動(dòng)窗口(效率機(jī)制)
剛才我們討論了確認(rèn)應(yīng)答策略,對(duì)每一個(gè)發(fā)送的數(shù)據(jù)段,都要給一個(gè)ACK確認(rèn)應(yīng)答。收到ACK后再發(fā)送 下一個(gè)數(shù)據(jù)段。這樣做有一個(gè)比較大的缺點(diǎn),就是性能較差。尤其是數(shù)據(jù)往返的時(shí)間較長(zhǎng)的時(shí)候。
既然這樣一發(fā)一收的方式性能較低,那么我們一次發(fā)送多條數(shù)據(jù),就可以大大的提高性能(其實(shí)是將多 個(gè)段的等待時(shí)間重疊在一起了)。
- 窗口大小:它指的是無(wú)需等待確認(rèn)應(yīng)答而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值。上圖的窗口大小就是4000
個(gè)字節(jié)(四個(gè)段)。- 發(fā)送前四個(gè)段的時(shí)候,不需要等待任何ACK,直接發(fā)送;
- 收到第一個(gè)ACK后,滑動(dòng)窗口向后移動(dòng),繼續(xù)發(fā)送第五個(gè)段的數(shù)據(jù);依次類推;(到一個(gè)ACK就繼續(xù)發(fā)一個(gè),讓等待的ACK始終都哦是窗口大小的數(shù)量)
- 操作系統(tǒng)內(nèi)核為了維護(hù)這個(gè)滑動(dòng)窗口,需要開(kāi)辟 發(fā)送緩沖區(qū) 來(lái)記錄當(dāng)前還有哪些數(shù)據(jù)沒(méi)有應(yīng)答;只有確認(rèn)應(yīng)答過(guò)的數(shù)據(jù),才能從緩沖區(qū)刪掉;
- 窗口越大,則網(wǎng)絡(luò)的吞吐率就越高;
那么如果出現(xiàn)了丟包,如何進(jìn)行重傳?這里分兩種情況討論。
情況一:數(shù)據(jù)包已經(jīng)抵達(dá),ACK被丟了。
這種情況下,部分ACK丟了并不要緊,因?yàn)榭梢酝ㄟ^(guò)后續(xù)的ACK進(jìn)行確認(rèn);
情況二:數(shù)據(jù)包就直接丟了。
- 由于1001 - 2000丟包了,接下來(lái)2001 - 3000 到達(dá)主機(jī) B 后,B 給 A 返回的 ACK 確認(rèn)序號(hào)仍然是 1001。(此時(shí)和你發(fā)來(lái)的這個(gè)數(shù)據(jù)序號(hào)是啥,關(guān)系不大,他不會(huì)返回當(dāng)前的這個(gè) ACK,而是返回目前已有的哪個(gè)最小的 ACK 確認(rèn)序號(hào))
- 當(dāng)某一段報(bào)文段丟失之后,發(fā)送端會(huì)一直收到 1001 這樣的ACK,就像是在提醒發(fā)送端 “我想要的是 1001” 一樣;
- 如果發(fā)送端主機(jī)連續(xù)三次收到了同樣一個(gè) “1001” 這樣的應(yīng)答,就會(huì)將對(duì)應(yīng)的數(shù)據(jù) 1001 - 2000 重新發(fā)送;
- 這個(gè)時(shí)候接收端收到了 1001 之后,再次返回的ACK就是7001了(因?yàn)?001 - 7000)接收端其實(shí)之前就已經(jīng)收到了,被放到了接收端操作系統(tǒng)內(nèi)核的接收緩沖區(qū)中;
這種機(jī)制被稱為 “高速重發(fā)控制”(也叫 “快重傳”)。
4.1.2.5流量控制(安全機(jī)制)- 接收方
接收端處理數(shù)據(jù)的速度是有限的。如果發(fā)送端發(fā)的太快,導(dǎo)致接收端的緩沖區(qū)被打滿,這個(gè)時(shí)候如果發(fā)送端繼續(xù)發(fā)送,就會(huì)造成丟包,繼而引起丟包重傳等等一系列連鎖反應(yīng)。
因此TCP支持根據(jù)接收端的處理能力,來(lái)決定發(fā)送端的發(fā)送速度。這個(gè)機(jī)制就叫做流量控制(Flow Control);
- 接收端將自己可以接收的緩沖區(qū)大小放入 TCP 首部中的 “窗口大小” 字段,通過(guò)ACK端通知發(fā)送端;
- 窗口大小字段越大,說(shuō)明網(wǎng)絡(luò)的吞吐量越高;
- 接收端一旦發(fā)現(xiàn)自己的緩沖區(qū)快滿了,就會(huì)將窗口大小設(shè)置成一個(gè)更小的值通知給發(fā)送端;
- 發(fā)送端接受到這個(gè)窗口之后,就會(huì)減慢自己的發(fā)送速度;
- 如果接收端緩沖區(qū)滿了,就會(huì)將窗口置為 0;這時(shí)發(fā)送方不再發(fā)送數(shù)據(jù),但是需要定期發(fā)送一個(gè)窗口探測(cè)數(shù)據(jù)段,使接收端把窗口大小告訴發(fā)送端。
接收端如何把窗口大小告訴發(fā)送端呢?回憶我們的TCP首部中,有一個(gè)16位窗口字段,就是存放了窗口 大小信息;
那么問(wèn)題來(lái)了,16位數(shù)字最大表示65535,那么TCP窗口最大就是65535字節(jié)么?
實(shí)際上,TCP首部40字節(jié)選項(xiàng)中還包含了一個(gè)窗口擴(kuò)大因子M,實(shí)際窗口大小是 窗口字段的值左移 M 位;
比如窗口大小已經(jīng)是 16位 即64kb 它里面的擴(kuò)展因子寫(xiě)了個(gè) 2,意思就是讓
64KB << 2 = > 256KB
由于接收方緩沖區(qū)剩余空間是一直在動(dòng)態(tài)變化的,所以每次返回 ack 帶的窗口大小都在變化,發(fā)送方也是在動(dòng)態(tài)調(diào)整。
4.1.2.6擁塞控制(安全機(jī)制)- 中間節(jié)點(diǎn)過(guò)程
雖然TCP有了滑動(dòng)窗口這個(gè)大殺器,能夠高效可靠的發(fā)送大量的數(shù)據(jù)。但是如果在剛開(kāi)始階段就發(fā)送大量的數(shù)據(jù),仍然可能引發(fā)問(wèn)題。
因?yàn)榫W(wǎng)絡(luò)上有很多的計(jì)算機(jī),可能當(dāng)前的網(wǎng)絡(luò)狀態(tài)就已經(jīng)比較擁堵。在不清楚當(dāng)前網(wǎng)絡(luò)狀態(tài)下,貿(mào)然發(fā) 送大量的數(shù)據(jù),是很有可能引起雪上加霜的。
TCP引入 慢啟動(dòng) 機(jī)制,先發(fā)少量的數(shù)據(jù),探探路,摸清當(dāng)前的網(wǎng)絡(luò)擁堵?tīng)顟B(tài),再?zèng)Q定按照多大的速度傳 輸數(shù)據(jù);
- 此處引入一個(gè)概念程為擁塞窗口
- 發(fā)送開(kāi)始的時(shí)候,定義擁塞窗口大小為1;
- 每次收到一個(gè)ACK應(yīng)答,擁塞窗口加1;
- 每次發(fā)送數(shù)據(jù)包的時(shí)候,將擁塞窗口和接收端主機(jī)反饋的窗口大小做比較,取較小的值作為實(shí)際發(fā)送的窗口;
像上面這樣的擁塞窗口增長(zhǎng)速度,是指數(shù)級(jí)別的?!奥龁?dòng)” 只是指初使時(shí)慢,但是增長(zhǎng)速度非???。
- 為了不增長(zhǎng)的那么快,因此不能使擁塞窗口單純的加倍。
- 此處引入一個(gè)叫做慢啟動(dòng)的閾值
- 當(dāng)擁塞窗口超過(guò)這個(gè)閾值的時(shí)候,不再按照指數(shù)方式增長(zhǎng),而是按照線性方式增長(zhǎng)
- 當(dāng)TCP開(kāi)始啟動(dòng)的時(shí)候,慢啟動(dòng)閾值等于窗口最大值;
- 在每次超時(shí)重發(fā)的時(shí)候,慢啟動(dòng)閾值會(huì)變成原來(lái)的一半,同時(shí)擁塞窗口置回1;
少量的丟包,我們僅僅是觸發(fā)超時(shí)重傳;大量的丟包,我們就認(rèn)為網(wǎng)絡(luò)擁塞;
當(dāng)TCP通信開(kāi)始后,網(wǎng)絡(luò)吞吐量會(huì)逐漸上升;隨著網(wǎng)絡(luò)發(fā)生擁堵,吞吐量會(huì)立刻下降;
擁塞控制,歸根結(jié)底是TCP協(xié)議想盡可能快的把數(shù)據(jù)傳輸給對(duì)方,但是又要避免給網(wǎng)絡(luò)造成太大壓力的 折中方案。
TCP擁塞控制這樣的過(guò)程,就好像 **熱戀的感覺(jué) **
4.1.2.7延遲應(yīng)答(效率機(jī)制)
如果接收數(shù)據(jù)的主機(jī)立刻返回ACK應(yīng)答,這時(shí)候返回的窗口可能比較小。
- 假設(shè)接收端緩沖區(qū)為1M。一次收到了500K的數(shù)據(jù);如果立刻應(yīng)答,返回的窗口就是500K;
- 但實(shí)際上可能處理端處理的速度很快,10ms之內(nèi)就把500K數(shù)據(jù)從緩沖區(qū)消費(fèi)掉了;
- 在這種情況下,接收端處理還遠(yuǎn)沒(méi)有達(dá)到自己的極限,即使窗口再放大一些,也能處理過(guò)來(lái);
- 如果接收端稍微等一會(huì)再應(yīng)答,比如等待200ms再應(yīng)答,那么這個(gè)時(shí)候返回的窗口大小就是 1M;
一定要記得,窗口越大,網(wǎng)絡(luò)吞吐量就越大,傳輸效率就越高。我們的目標(biāo)是在保證網(wǎng)絡(luò)不擁塞的情況 下盡量提高傳輸效率;
那么所有的包都可以延遲應(yīng)答么?肯定也不是;
- 數(shù)量限制:每隔N個(gè)包就應(yīng)答一次;
- 時(shí)間限制:超過(guò)最大延遲時(shí)間就應(yīng)答一次;
具體的數(shù)量和超時(shí)時(shí)間,依操作系統(tǒng)不同也有差異;一般N取2,超時(shí)時(shí)間取200ms;
4.1.2.8捎帶應(yīng)答(效率機(jī)制)
在延遲應(yīng)答的基礎(chǔ)上,我們發(fā)現(xiàn),很多情況下,客戶端服務(wù)器在應(yīng)用層也是 “一發(fā)一收” 的。意味著客戶端給服務(wù)器說(shuō)了 “How are you”,服務(wù)器也會(huì)給客戶端回一個(gè) “Fine, thank you”;
那么這個(gè)時(shí)候ACK就可以搭順風(fēng)車,和服務(wù)器回應(yīng)的 “Fine,thank you” 一起回給客戶端
本來(lái)是不同實(shí)際,在延時(shí)應(yīng)答下,可能成為相同的時(shí)機(jī),就合并了。
TCP 三次握手,本身就是相同時(shí)機(jī)。
三次握手是一定會(huì)合并的,此處有一定概率合并,這里和 四次揮手 的合并更像!
其他特性:面向字節(jié)流
其他特性:緩沖區(qū)
**其他特性:大小限制 **
創(chuàng)建一個(gè)TCP的socket,同時(shí)在內(nèi)核中創(chuàng)建一個(gè) 發(fā)送緩沖區(qū) 和一個(gè) 接收緩沖區(qū);
- 調(diào)用 write時(shí),數(shù)據(jù)會(huì)先寫(xiě)入發(fā)送緩沖區(qū)中;
- 如果發(fā)送的字節(jié)數(shù)太長(zhǎng),會(huì)被拆分成多個(gè) TCP的數(shù)據(jù)包發(fā)出;
- 如果發(fā)送的字節(jié)數(shù)太短,就會(huì)先在緩沖區(qū)里等待,等到緩沖區(qū)長(zhǎng)度差不多了,或者其他合適 的時(shí)機(jī)發(fā)送出去;
- 接收數(shù)據(jù)的時(shí)候,數(shù)據(jù)也是從網(wǎng)卡驅(qū)動(dòng)程序到達(dá)內(nèi)核的接收緩沖區(qū);
- 然后應(yīng)用程序可以調(diào)用read從接收緩沖區(qū)拿數(shù)據(jù);
- 另一方面,TCP的一個(gè)連接,既有發(fā)送緩沖區(qū),也有接收緩沖區(qū),那么對(duì)于這一個(gè)連接,既 可以讀數(shù)據(jù),也可以寫(xiě)數(shù)據(jù)。這個(gè)概念叫做 全雙工
由于緩沖區(qū)的存在,TCP程序的讀和寫(xiě)不需要一一匹配,例如:
- 寫(xiě) 100個(gè)字節(jié)數(shù)據(jù)時(shí),可以調(diào)用一次 write寫(xiě) 100個(gè)字節(jié),也可以調(diào)用100次 write,每次寫(xiě)一個(gè)字節(jié);
- 讀100個(gè)字節(jié)數(shù)據(jù)時(shí),也完全不需要考慮寫(xiě)的時(shí)候是怎么寫(xiě)的,既可以一次read 100個(gè)字 節(jié),也可以一次read一個(gè)字節(jié),重復(fù)100次;
4.1.3粘包問(wèn)題
[八戒吃饅頭例子]
- 首先要明確,粘包問(wèn)題中的 "包 " ,是指的應(yīng)用層的數(shù)據(jù)包。
- 在TCP的協(xié)議頭中,沒(méi)有如同 UDP一樣的 “報(bào)文長(zhǎng)度” 這樣的字段,但是有一個(gè)序號(hào)這樣的字段。
- 站在傳輸層的角度,TCP是一個(gè)一個(gè)報(bào)文過(guò)來(lái)的。
- 按照序號(hào)排好序放在緩沖區(qū)中。 站在應(yīng)用層的角度,看到的只是一串連續(xù)的字節(jié)數(shù)據(jù)。
- 那么應(yīng)用程序看到了這么一連串的字節(jié)數(shù)據(jù),就不知道從哪個(gè)部分開(kāi)始到哪個(gè)部分,是一個(gè) 完整的應(yīng)用層數(shù)據(jù)包。
那么如何避免粘包問(wèn)題呢?歸根結(jié)底就是一句話,明確兩個(gè)包之間的邊界。
- 對(duì)于定長(zhǎng)的包,保證每次都按固定大小讀取即可;例如上面的 Request結(jié)構(gòu),是固定大小的,那么就從緩沖區(qū)從頭開(kāi)始按 sizeof(Request)依次讀取即可;
- 對(duì)于變長(zhǎng)的包,可以在包頭的位置,約定一個(gè)包總長(zhǎng)度的字段,從而就知道了包的結(jié)束位置;
- 對(duì)于變長(zhǎng)的包,還可以在包和包之間使用明確的分隔符(應(yīng)用層協(xié)議,是程序猿自己來(lái)定的,只要保證分隔符不和正文沖突即可);
思考:對(duì)于UDP協(xié)議來(lái)說(shuō),是否也存在 “粘包問(wèn)題” 呢?
- 對(duì)于 UDP,如果還沒(méi)有上層交付數(shù)據(jù),UDP的報(bào)文長(zhǎng)度仍然在。同時(shí),UDP是一個(gè)一個(gè)把數(shù) 據(jù)交付給應(yīng)用層。就有很明確的數(shù)據(jù)邊界。
- 站在應(yīng)用層的站在應(yīng)用層的角度,使用 UDP的時(shí)候,要么收到完整的 UDP報(bào)文,要么不收。 不會(huì)出現(xiàn) "半個(gè) "的情況。
4.1.4TCP異常情況
進(jìn)程終止:進(jìn)程終止會(huì)釋放文件描述符,仍然可以發(fā)送FIN。和正常關(guān)閉沒(méi)有什么區(qū)別。 相當(dāng)于 socket.close()
機(jī)器重啟:和進(jìn)程終止的情況相同。
機(jī)器掉電/網(wǎng)線斷開(kāi):接收端認(rèn)為連接還在,一旦接收端有寫(xiě)入操作,接收端發(fā)現(xiàn)連接已經(jīng)不在了,就會(huì) 進(jìn)行reset。即使沒(méi)有寫(xiě)入操作,TCP自己也內(nèi)置了一個(gè)?;疃〞r(shí)器,會(huì)定期詢問(wèn)對(duì)方是否還在。如果對(duì)方不在,也會(huì)把連接釋放。
另外,應(yīng)用層的某些協(xié)議,也有一些這樣的檢測(cè)機(jī)制。例如HTTP長(zhǎng)連接中,也會(huì)定期檢測(cè)對(duì)方的狀態(tài)。 例如QQ,在QQ斷線之后,也會(huì)定期嘗試重新連接。
心跳包:就是在客戶端和服務(wù)器間定時(shí)通知對(duì)方自己狀態(tài)的一個(gè)自己定義的命令字,按照一定的時(shí)間間隔發(fā)送,類似于心跳,所以叫做心跳包。
A發(fā)送一個(gè)心跳包,那么B也會(huì)回復(fù)一個(gè)心跳包,如果B沒(méi)有回一個(gè)心跳包,那么就是B機(jī)器掛了。
4.1.5TCP小結(jié)
為什么TCP這么復(fù)雜?因?yàn)橐WC可靠性,同時(shí)又盡可能的提高性能。
可靠性:
- 校驗(yàn)和
- 序列號(hào)(按序到達(dá))
- 確認(rèn)應(yīng)答
- 超時(shí)重發(fā)
- 連接管理
- 流量控制
- 擁塞控制
提高性能:
- 滑動(dòng)窗口
- 快速重傳
- 延遲應(yīng)答
- 捎帶應(yīng)答
其他:
- 定時(shí)器(超時(shí)重傳定時(shí)器,?;疃〞r(shí)器,TIME_WAIT定時(shí)器等)
4.1.6基于TCP應(yīng)用層協(xié)議
- HTTP
- HTTPS
- SSH
- Telnet
- FTP
- SMTP
當(dāng)然,也包括你自己寫(xiě)TCP程序時(shí)自定義的應(yīng)用層協(xié)議;
4.2UDP協(xié)議
4.2.1UDP協(xié)議端格式
- 16位 UDP長(zhǎng)度,表示整個(gè)數(shù)據(jù)報(bào)(UDP首部+UDP數(shù)據(jù))的最大長(zhǎng)度;
- 如果校驗(yàn)和出錯(cuò),就會(huì)直接丟棄;
4.2.2UDP的特點(diǎn)
UDP傳輸?shù)倪^(guò)程類似于寄信。
無(wú)連接
知道對(duì)端的IP和端口號(hào)就直接進(jìn)行傳輸,不需要建立連接;
不可靠
沒(méi)有任何安全機(jī)制,發(fā)送端發(fā)送數(shù)據(jù)報(bào)以后,如果因?yàn)榫W(wǎng)絡(luò)故障該段無(wú)法發(fā)到對(duì)方,UDP協(xié)議層也不會(huì) 給應(yīng)用層返回任何錯(cuò)誤信息;
面向數(shù)據(jù)報(bào)
應(yīng)用層交給UDP多長(zhǎng)的報(bào)文,UDP原樣發(fā)送,既不會(huì)拆分,也不會(huì)合并;
用UDP傳輸100個(gè)字節(jié)的數(shù)據(jù):
如果發(fā)送端一次發(fā)送 100個(gè)字節(jié),那么接收端也必須一次接收 100個(gè)字節(jié);而不能循環(huán)接收 10次, 每次接收 10個(gè)字節(jié)。
緩沖區(qū)
UDP只有接收緩沖區(qū),沒(méi)有發(fā)送緩沖區(qū):
UDP沒(méi)有真正意義上的 發(fā)送緩沖區(qū)。發(fā)送的數(shù)據(jù)會(huì)直接交給內(nèi)核,由內(nèi)核將數(shù)據(jù)傳給網(wǎng)絡(luò)層協(xié)議 進(jìn)行后續(xù)的傳輸動(dòng)作;
UDP具有接收緩沖區(qū),但是這個(gè)接收緩沖區(qū)不能保證收到的 UDP報(bào)的順序和發(fā)送UDP報(bào)的順序一 致;如果緩沖區(qū)滿了,再到達(dá)的 UDP數(shù)據(jù)就會(huì)被丟棄;
UDP的socket既能讀,也能寫(xiě),這個(gè)概念叫做 全雙工
大小受限
UDP協(xié)議首部中有一個(gè)16位的最大長(zhǎng)度。也就是說(shuō)一個(gè)UDP能傳輸?shù)臄?shù)據(jù)最大長(zhǎng)度是64K(包含UDP首 部)。
4.2.3基于UDP的應(yīng)用層協(xié)議
- NFS:網(wǎng)絡(luò)文件系統(tǒng)
- TFTP:簡(jiǎn)單文件傳輸協(xié)議
- DHCP:動(dòng)態(tài)主機(jī)配置協(xié)議
- BOOTP:啟動(dòng)協(xié)議(用于無(wú)盤設(shè)備啟動(dòng))
- DNS:域名解析協(xié)議
當(dāng)然,也包括你自己寫(xiě)UDP程序時(shí)自定義的應(yīng)用層協(xié)議。
4.2.4擴(kuò)展問(wèn)題
這是一個(gè)經(jīng)典面試題:
- UDP本身是無(wú)連接,不可靠,面向數(shù)據(jù)報(bào)的協(xié)議,如果要基于傳輸層UDP協(xié)議,來(lái)實(shí)現(xiàn)一個(gè)可靠傳 輸,應(yīng)該如何設(shè)計(jì)?
- UDP大小是受限的,如果要基于傳輸層UDP協(xié)議,傳輸超過(guò)64K的數(shù)據(jù),應(yīng)該如何設(shè)計(jì)?
以上兩個(gè)問(wèn)題答案類似,都可以參考TCP的可靠性機(jī)制在應(yīng)用層實(shí)現(xiàn)類似的邏輯:
例如:
- 引入序列號(hào),保證數(shù)據(jù)順序;
- 引入確認(rèn)應(yīng)答,確保對(duì)端收到了數(shù)據(jù);
- 引入超時(shí)重傳,如果隔一段時(shí)間沒(méi)有應(yīng)答,就重發(fā)數(shù)據(jù);
- ……
4.3TCP/UDP對(duì)比
我們說(shuō)了TCP是可靠連接,那么是不是TCP一定就優(yōu)于UDP呢?TCP和UDP之間的優(yōu)點(diǎn)和缺點(diǎn),不能簡(jiǎn)單,絕對(duì)的進(jìn)行比較
- TCP用于可靠傳輸的情況,應(yīng)用于文件傳輸,重要狀態(tài)更新等場(chǎng)景;
- UDP用于對(duì)高速傳輸和實(shí)時(shí)性要求較高的通信領(lǐng)域,例如,早期的QQ,視頻傳輸?shù)?。另?UDP可以用于廣播;
歸根結(jié)底,TCP和UDP都是程序員的工具,什么時(shí)機(jī)用,具體怎么用,還是要根據(jù)具體的需求場(chǎng)景去判定。
例如我們?cè)趯W(xué)校的機(jī)房里,可靠性就比較高,我們?yōu)榱俗非笏俣葧?huì)使用UDP來(lái)進(jìn)行各個(gè)電腦間的通信。
5.網(wǎng)絡(luò)層重點(diǎn)協(xié)議
在復(fù)雜的網(wǎng)絡(luò)環(huán)境中確定一個(gè)合適的路徑。
5.1IP協(xié)議
協(xié)議頭格式如下:
- 4位版本號(hào)(version):指定IP協(xié)議的版本,對(duì)于IPv4來(lái)說(shuō),就是4。
- 4位首部長(zhǎng)度(header length):IP頭部的長(zhǎng)度是多少個(gè)32bit,也就是 length * 4 的字節(jié) 數(shù)。4bit表示最大的數(shù)字是15,因此IP頭部最大長(zhǎng)度是60字節(jié)。
- 8位服務(wù)類型(Type Of Service):3位優(yōu)先權(quán)字段(已經(jīng)棄用),4位TOS字段,和 1位保留字段(必須置為 0)。4位 TOS分別表示:最小延時(shí),最大吞吐量,最高可靠性,最小成本。 這四者相互沖突,只能選擇一個(gè)。對(duì)于 ssh/telnet這樣的應(yīng)用程序,最小延時(shí)比較重要;對(duì)于 ftp這樣的程序,最大吞吐量比較重要。
- 16位總長(zhǎng)度(total length):IP數(shù)據(jù)報(bào)整體占多少個(gè)字節(jié)。
這里的16位總長(zhǎng)度是否意味著一個(gè) IP 數(shù)據(jù)報(bào),最大只能支持 64 KB?
確實(shí)是有這個(gè)限制的,但是 IP 自身就支持對(duì)包的拆分和組裝,一個(gè) IP 數(shù)據(jù)報(bào)攜帶的數(shù)據(jù)載荷太長(zhǎng)了,超過(guò)了 64KB,就會(huì)在網(wǎng)絡(luò)層針對(duì)數(shù)據(jù)進(jìn)行拆分。比一個(gè)數(shù)據(jù)拆分成多個(gè) IP 數(shù)據(jù)報(bào),再分別發(fā)送。接收方收到后,再重新拼裝。
例如要傳輸一個(gè) 100KB 的數(shù)據(jù),網(wǎng)絡(luò)層就會(huì)把這個(gè) 100KB 的數(shù)據(jù)拆包(比如拆成兩份) 64KB + 36KB,這兩份再交給數(shù)據(jù)鏈路層,由以太網(wǎng)分裝成兩個(gè)數(shù)據(jù)幀。
接收方:數(shù)據(jù)鏈路層,針對(duì)兩個(gè)數(shù)據(jù)幀進(jìn)行分用,得到兩個(gè) ip 數(shù)據(jù)報(bào),交給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層針對(duì)這倆 IP 數(shù)據(jù)報(bào)進(jìn)行解析,把里面的載荷拼成一個(gè),交給傳輸層…- 16位標(biāo)識(shí)(id):唯一的標(biāo)識(shí)主機(jī)發(fā)送的報(bào)文。如果 IP報(bào)文在數(shù)據(jù)鏈路層被分片了,那么每一個(gè)片里面的這個(gè) id都是相同的。
- 3位標(biāo)志字段:第一位保留(保留的意思是現(xiàn)在不用,但是還沒(méi)想好說(shuō)不定以后要用到)。第 二位置為1表示禁止分片,這時(shí)候如果報(bào)文長(zhǎng)度超過(guò)MTU,IP模塊就會(huì)丟棄報(bào)文。第三位表 示"更多分片",如果分片了的話,最后一個(gè)分片置為1,其他是 0。類似于一個(gè)結(jié)束標(biāo)記。
- 13位分片偏移(framegament offset):是分片相對(duì)于原始 IP報(bào)文開(kāi)始處的偏移。其實(shí)就是 在表示當(dāng)前分片在原報(bào)文中處在哪個(gè)位置。實(shí)際偏移的字節(jié)數(shù)是這個(gè)值 * 8 得到的。因此, 除了最后一個(gè)報(bào)文之外,其他報(bào)文的長(zhǎng)度必須是 8的整數(shù)倍(否則報(bào)文就不連續(xù)了)。
- 8位生存時(shí)間(Time To Live,TTL):數(shù)據(jù)報(bào)到達(dá)目的地的最大報(bào)文跳數(shù)。一般是 64。每次 經(jīng)過(guò)一個(gè)路由,TTL -= 1,一直減到 0還沒(méi)到達(dá),那么就丟棄了。這個(gè)字段主要是用來(lái)防止出現(xiàn)路由循環(huán)。
8位協(xié)議:表示上層協(xié)議的類型。
16位頭部校驗(yàn)和:使用CRC進(jìn)行校驗(yàn),來(lái)鑒別頭部是否損壞。
32位源地址和 32位目標(biāo)地址:表示發(fā)送端和接收端。
我們?nèi)粘I钪械?IP 則是一串?dāng)?shù)字。
把 32位,4個(gè)字節(jié)的數(shù)字給分割開(kāi),分成 4個(gè)部分。每個(gè)部分分別使用 0-255 十進(jìn)制整數(shù)表示。
點(diǎn)分十進(jìn)制
但是我們 32 位數(shù)字只能表示 42億9千萬(wàn)個(gè)數(shù)字,當(dāng)前設(shè)備已經(jīng)超出這個(gè)數(shù)字了,我們?cè)趺唇鉀Q IP 地址不夠用的問(wèn)題呢?
答:
- 動(dòng)態(tài)分配 IP 地址,此時(shí)就可以省下一批 IP地址了。(并沒(méi)有從根本上增加 IP 地址,只提高了利用率,治標(biāo)不治本)
- NAT 網(wǎng)絡(luò)地址轉(zhuǎn)換。本質(zhì)是使用一個(gè) IP 表示一批設(shè)備。
外網(wǎng)IP
內(nèi)網(wǎng)IP (10.,172.16.-172.31.*,192.168.**)- IPv6 根本上解決了 IP 不夠用的問(wèn)題 使用 16 字節(jié)表示 IP 地址 128位 相當(dāng)于 42億9千萬(wàn)個(gè)數(shù)字的四次方個(gè)數(shù)字。雖然 IPv6 看起來(lái)非常美好,但是世界上,仍然是以 NAT + IPv4 + 動(dòng)態(tài)分配來(lái)進(jìn)行網(wǎng)絡(luò)組建的。真正使用 IPv6 的地方非常非常少!!!
那么為什么 IPv6 使用非常少呢,因?yàn)橘F!!! IPv6 和 IPv4 不兼容。選項(xiàng)字段(不定長(zhǎng),最多 40字節(jié)):略。
6.數(shù)據(jù)鏈路層重點(diǎn)協(xié)議
6.1認(rèn)識(shí)以太網(wǎng)
- "以太網(wǎng) " 不是一種具體的網(wǎng)絡(luò),而是一種技術(shù)標(biāo)準(zhǔn);既包含了數(shù)據(jù)鏈路層的內(nèi)容,也包含了 一些物理層的內(nèi)容。
- 例如:規(guī)定了網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu),訪問(wèn)控制方式,傳輸速率等; 例如以太網(wǎng)中的網(wǎng)線必須使用雙絞線;傳輸速率有10M,100M,1000M等;
- 以太網(wǎng)是當(dāng)前應(yīng)用最廣泛的局域網(wǎng)技術(shù);和以太網(wǎng)并列的還有令牌環(huán)網(wǎng),無(wú)線 LAN等;
6.1.1以太網(wǎng)幀格式
以太網(wǎng)數(shù)據(jù)幀 = 幀頭 + 載荷 + 幀尾
幀頭(目的地址 源地址 類型) 載荷(完整的 IP 數(shù)據(jù)報(bào)) 幀尾()
以太網(wǎng)的幀格式如下所示:
- 源地址和目的地址是指網(wǎng)卡的硬件地址(也叫 MAC地址 - 6個(gè)字節(jié) 物理地址),長(zhǎng)度是48位,是在網(wǎng)卡出廠時(shí)固化的;
- 幀協(xié)議類型字段有三種值,分別對(duì)應(yīng) IP、ARP、RARP;
- 幀末尾是CRC校驗(yàn)碼。
6.1.2 IP地址 和 mac地址有啥區(qū)別嗎?
想必大家都有一個(gè)疑問(wèn)吧,那就是既然有了 IP地址 ,為什么還要?jiǎng)?chuàng)造一個(gè) mac 地址呢?
這其實(shí)是一個(gè)悲傷的故事,加入只有一套地址體系 (比如 IP 和 以太網(wǎng)都是用 IP地址/mac地址) 是完全可以玩得轉(zhuǎn)的
但是最開(kāi)始大佬們研發(fā)初代的協(xié)議棧的時(shí)候,研發(fā) 網(wǎng)絡(luò)層協(xié)議 和 研發(fā) 數(shù)據(jù)鏈路層協(xié)議 的大佬是兩伙人,他們各自獨(dú)立的研發(fā)出了一套地址體系。最后雙方大佬各用各的地址,于是就演化成了兩套地址體系,相互配合使用。
那么 IP 和 mac 是如何配合的呢?
IP 用來(lái)描述爭(zhēng)個(gè)整個(gè)傳輸過(guò)程的起點(diǎn)終點(diǎn)。 mac 則是用來(lái)描述 兩個(gè)相鄰節(jié)點(diǎn),起點(diǎn)終點(diǎn)(各司其職)
IP做的事情:
mac做的事情:
總結(jié):IP 描述的是 “初心”,最初從哪來(lái)到哪去,最初的目標(biāo)是啥?
mac 描述的是 當(dāng)前階段 的任務(wù)。
6.2認(rèn)識(shí)MTU(對(duì)于較大的IP數(shù)據(jù)包要進(jìn)行分包)
MTU相當(dāng)于發(fā)快遞時(shí)對(duì)包裹尺寸的限制。這個(gè)限制是不同的數(shù)據(jù)鏈路對(duì)應(yīng)的物理層,產(chǎn)生的限制。
- 以太網(wǎng)幀中的數(shù)據(jù)長(zhǎng)度規(guī)定最小 46字節(jié),最大1500字節(jié),ARP數(shù)據(jù)包的長(zhǎng)度不夠 46字節(jié),要在后面補(bǔ)填充位;
- 最大值1500稱為以太網(wǎng)的最大傳輸單元(MTU),不同的網(wǎng)絡(luò)類型有不同的MTU;
- 如果一個(gè)數(shù)據(jù)包從以太網(wǎng)路由到撥號(hào)鏈路上,數(shù)據(jù)包長(zhǎng)度大于撥號(hào)鏈路的MTU了,則需要對(duì)數(shù)據(jù)包進(jìn)行分片(fragmentation);
- 不同的數(shù)據(jù)鏈路層標(biāo)準(zhǔn)的MTU是不同的;
6.2.1MTU對(duì)IP協(xié)議的影響
由于數(shù)據(jù)鏈路層MTU的限制,對(duì)于較大的IP數(shù)據(jù)包要進(jìn)行分包。
- 將較大的IP包分成多個(gè)小包,并給每個(gè)小包打上標(biāo)簽;
- 每個(gè)小包IP協(xié)議頭的 16位標(biāo)識(shí)(id) 都是相同的;
- 每個(gè)小包的IP協(xié)議頭的 3位標(biāo)志字段中,第 2位置為 0,表示允許分片,第 3位來(lái)表示結(jié)束標(biāo)記 (當(dāng)前是否是最后一個(gè)小包,是的話置為1,否則置為 0);
- 到達(dá)對(duì)端時(shí)再將這些小包,會(huì)按順序重組,拼裝到一起返回給傳輸層;
- 一旦這些小包中任意一個(gè)小包丟失,接收端的重組就會(huì)失敗。但是IP層不會(huì)負(fù)責(zé)重新傳輸數(shù)據(jù);
6.2.2MTU對(duì)UDP協(xié)議的影響
讓我們回顧一下UDP協(xié)議:
- 一旦UDP攜帶的數(shù)據(jù)超過(guò) 1472(1500 - 20(IP首部) - 8(UDP首部)),那么就會(huì)在網(wǎng)絡(luò)層分成多個(gè)IP數(shù)據(jù)報(bào)。
- 這多個(gè)IP數(shù)據(jù)報(bào)有任意一個(gè)丟失,都會(huì)引起接收端網(wǎng)絡(luò)層重組失敗。那么這就意味著,如果 UDP數(shù)據(jù)報(bào)在網(wǎng)絡(luò)層被分片,整個(gè)數(shù)據(jù)被丟失的概率就大大增加了。
6.2.3MTU對(duì)于TCP協(xié)議的影響
讓我們?cè)倩仡櫼幌耇CP協(xié)議:
- TCP的一個(gè)數(shù)據(jù)報(bào)也不能無(wú)限大,還是受制于 MTU。TCP的單個(gè)數(shù)據(jù)報(bào)的最大消息長(zhǎng)度,稱為 MSS(Max Segment Size);
- TCP在建立連接的過(guò)程中,通信雙方會(huì)進(jìn)行 MSS協(xié)商。
- 最理想的情況下,MSS的值正好是在 IP不會(huì)被分片處理的最大長(zhǎng)度(這個(gè)長(zhǎng)度仍然是受制于 數(shù)據(jù)鏈路層的 MTU)。
- 雙方在發(fā)送 SYN的時(shí)候會(huì)在 TCP頭部寫(xiě)入自己能支持的 MSS值。
- 然后雙方得知對(duì)方的 MSS值之后,選擇較小的作為最終 MSS。
- MSS的值就是在 TCP首部的40字節(jié)變長(zhǎng)選項(xiàng)中( kind=2);
MSS和MTU的關(guān)系
6.3ARP協(xié)議
雖然我們?cè)谶@里介紹ARP協(xié)議,但是需要強(qiáng)調(diào),ARP不是一個(gè)單純的數(shù)據(jù)鏈路層的協(xié)議,而是一個(gè)介于 數(shù)據(jù)鏈路層和網(wǎng)絡(luò)層之間的協(xié)議;
6.3.1ARP協(xié)議的作用(直到 ip 通過(guò) ARP 來(lái)返回 mac)
ARP協(xié)議建立了主機(jī) IP地址 和 MAC地址 的映射關(guān)系。
- 在網(wǎng)絡(luò)通訊時(shí),源主機(jī)的應(yīng)用程序知道目的主機(jī)的 IP地址和端口號(hào),卻不知道目的主機(jī)的硬件地址;
- 數(shù)據(jù)包首先是被網(wǎng)卡接收到再去處理上層協(xié)議的,如果接收到的數(shù)據(jù)包的硬件地址與本機(jī)不符,則直接丟棄;
- 因此在通訊前必須獲得目的主機(jī)的硬件地址;
6.3.2ARP協(xié)議的工作流程
- 源主機(jī)發(fā)出ARP請(qǐng)求,詢問(wèn)“IP地址是192.168.0.1的主機(jī)的硬件地址是多少”,并將這個(gè)請(qǐng)求廣播到本地網(wǎng)段(以太網(wǎng)幀首部的硬件地址填FF:FF:FF:FF:FF:FF表示廣播);
- 目的主機(jī)接收到廣播的ARP請(qǐng)求,發(fā)現(xiàn)其中的 IP地址與本機(jī)相符,則發(fā)送一個(gè)ARP應(yīng)答數(shù)據(jù)包 給源主機(jī),將自己的硬件地址填寫(xiě)在應(yīng)答包中;
- 每臺(tái)主機(jī)都維護(hù)一個(gè)ARP緩存表,可以用arp -a命令查看。緩存表中的表項(xiàng)有過(guò)期時(shí)間(一般 為20分鐘),如果20分鐘內(nèi)沒(méi)有再次使用某個(gè)表項(xiàng),則該表項(xiàng)失效,下次還要發(fā)ARP請(qǐng)求來(lái) 獲得目的主機(jī)的硬件地址
7.總結(jié)
7.1數(shù)據(jù)鏈路層
- 數(shù)據(jù)鏈路層的作用:兩個(gè)設(shè)備(同一種數(shù)據(jù)鏈路節(jié)點(diǎn))之間進(jìn)行傳遞數(shù)據(jù)
- 以太網(wǎng)是一種技術(shù)標(biāo)準(zhǔn);既包含了數(shù)據(jù)鏈路層的內(nèi)容,也包含了一些物理層的內(nèi)容。例如: 規(guī)定了網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu),訪問(wèn)控制方式,傳輸速率等;
- 以太網(wǎng)幀格式
- 理解mac地址
- 理解arp協(xié)議
- 理解MTU
7.2網(wǎng)絡(luò)層
- 網(wǎng)絡(luò)層的作用:在復(fù)雜的網(wǎng)絡(luò)環(huán)境中確定一個(gè)合適的路徑。
- 理解 IP地址,理解 IP地址和 MAC地址的區(qū)別。
- 理解 IP協(xié)議格式。
- 了解網(wǎng)段劃分方法
- 理解如何解決 IP數(shù)目不足的問(wèn)題,掌握網(wǎng)段劃分的兩種方案。
- 理解私有 IP和公網(wǎng) IP 理解網(wǎng)絡(luò)層的 IP地址路由過(guò)程。理解一個(gè)數(shù)據(jù)包如何跨越網(wǎng)段到達(dá)最終目的地。
- 理解 IP數(shù)據(jù)包分包的原因。
- 了解 NAT設(shè)備的工作原理。
7.3傳輸層
- 傳輸層的作用:負(fù)責(zé)數(shù)據(jù)能夠從發(fā)送端傳輸接收端。
- 理解端口號(hào)的概念。 認(rèn)識(shí) UDP協(xié)議,了解 UDP協(xié)議的特點(diǎn)。
- 認(rèn)識(shí) TCP協(xié)議,理解 TCP協(xié)議的可靠性。理解 TCP協(xié)議的狀態(tài)轉(zhuǎn)化。
- 掌握 TCP的連接管理,確認(rèn)應(yīng)答,超時(shí)重傳,滑動(dòng)窗口,流量控制,擁塞控制,延遲應(yīng)答, 捎帶應(yīng)答特性。
- 理解 TCP面向字節(jié)流,理解粘包問(wèn)題和解決方案。
- 能夠基于 UDP實(shí)現(xiàn)可靠傳輸。
- 理解 MTU對(duì) UDP / TCP的影響。
7.4應(yīng)用層
- 應(yīng)用層的作用:滿足我們?nèi)粘P枨蟮木W(wǎng)絡(luò)程序,都是在應(yīng)用層
- 能夠根據(jù)自己的需求,設(shè)計(jì)應(yīng)用層協(xié)議。
- 了解HTTP協(xié)議。
- 理解DNS的原理和工作流程。
感謝各位讀者的閱讀,本文章有任何錯(cuò)誤都可以在評(píng)論區(qū)發(fā)表你們的意見(jiàn),我會(huì)對(duì)文章進(jìn)行改正的。如果本文章對(duì)你有幫助請(qǐng)動(dòng)一動(dòng)你們敏捷的小手點(diǎn)一點(diǎn)贊,你的每一次鼓勵(lì)都是作者創(chuàng)作的動(dòng)力哦!😘