1. 程式人生 > >NODE - 前置知識(網際網路協議)

NODE - 前置知識(網際網路協議)

初步瞭解網際網路:

//什麼是網際網路?
網際網路的實現分很多層,每層都有自己的功能且依賴下層。
每一層為了實現各自的功能,約定大家需要共同遵守的“協議”,這些協議的總稱就是“網際網路協議”。
“網際網路協議”對電腦如何連線和組網做了詳細的規定,理解了這些協議,就理解了網際網路的原理。

//什麼是網路通訊?
網路通訊的本質就是交換資料包。
A向B發了個數據包,B又給A回了個數據包,AB間就實現了通訊。
接下來要學習五層網路模型,就是要了解資料包的構成和通訊流程。

 

五層網路模型:

實體層:

把電腦連線起來的物理手段,規定了網路的電器特性,用來傳送 0 和 1 的電訊號。

連結層:在“實體層”上方,確定 0 和 1 的分組方式。

//乙太網協議
早期各家公司都有自己的電訊號分組方式,後來 乙太網協議 勝出成為主流。

//
一組電訊號構成一個數據包,叫做 幀,每一幀由 Head 和 Data 組成。
Head(18位元組),包含資料包的說明項(傳送者、接受者、型別)。
Data(46~64位元組),包含具體內容,資料長的話要分幀傳送。

//MAC地址
連入網路的所有裝置,都必須具有網絡卡介面,資料包必須從一塊網絡卡,傳送到另一塊網絡卡。
MAC地址 就是網絡卡的地址,也就是資料包的傳送地址和接收地址。
MAC地址 通常是一個12位16進位制數,前6位為廠商編號,後6位為廠商網絡卡流水號。
每塊網絡卡出廠時都有唯一 MAC地址(並非全球唯一,但基本不會撞)。

//廣播 傳送資料 - 向本網路內所有計算機發送,由計算機自行判斷是否接收。 接收資料 - 判斷 HEAD 中的接收地址,與自己的 MAC地址 是否相同,相同就接收。

網路層:引入一套“網路地址”,用來區分計算機是否屬於同一子網。

//網路層的由來
乙太網 以廣播的形式發包,效率較低,無法應用於大型網路。
因此我們將網際網路劃分成無數個子網,子網內以廣播形式發包,子網間以路由形式發包。
即,先用 網址 確定找到子網,再用 MAC地址 找到具體計算機。

//IP協議
IP資料包:
在資料傳送時,IP資料包 會被直接放入 以太資料包 的 DATA 中。
HEAD - 20~40位元組,包含版本、長度、IP地址等。
DATA 
- 具體資料。 IP地址: 規定 網址 的協議叫做 IP協議 ,所以 網址 就是 IP地址。 IP地址 由32個二進位制陣列成,習慣將其劃分成四段十進位制數。 IP地址 由兩部分組成,前面的若干位代表網路,剩餘的若干位代表主機。 //子網掩碼 單從 IP地址 無法判斷它的前多少位代表網路,所以引入 子網掩碼。 子網掩碼 由32個二進位制陣列成,網路部分全是1,主機部分全是0。 假設: IP地址為 - 192.168.0.1 子網掩碼為 - 255.255.255.0 這就說明 - 該IP地址是 192.168.0.x 區域網中的一臺主機 //路由 區域網間由路由器連線,路由器內有一張路由表,規定不同IP目的地資料包要傳送到哪個網口。 我們要在網路中找到一個具體網址,就要先讓路由器告訴我們這個網址對應的子網是誰。 可以把路由器理解為儲存了一套指路牌的機器,這些指路牌可以幫助我們實現資料包的轉發。 //ARP協議 傳送資料時我們需要同時知道對方的 MAC地址 和 IP地址 ,通常 IP地址 已知。 取得MAC地址: 兩臺主機不在同一子網,將資料包傳送到子網閘道器,讓它處理。 兩臺主機在同一子網,可以用ARP協議取得對方MAC地址。 ARP資料包: 填寫待查主機 IP地址,將 對方MAC地址 寫成 FF:FF:FF:FF:FF:FF,說明自己是一條廣播。 子網中的主機收到這條廣播,取出其中的 IP地址 與自己比對,相同則回覆本機 MAC地址。 注意: ARP協議是 連結層 協議,放這裡說是為了方便理解,它的資料包隨 以太資料包 傳送。

傳輸層:“網路層”實現主機到主機,“傳輸層”實現埠到埠。

//
同一臺主機上有多個程式需要用到網路資源,為了對應到具體程式,所以引入 埠 作為標記。
埠號是 0~65535 的整數,其中 0~1023 被系統佔用,Unix系統把“主機 + 埠”叫做 套接字(Socket)。

//UDP協議:“傳輸層”最簡單的協議
UDP資料包:
資料傳送時將 UDP資料包 放入 IP資料包 的 DATA中。
HEAD - 8位元組,定義發出埠和接收埠。
DATA - 具體資料。
UDP應用場景:
App應用,DNS查詢,廣播傳輸,流媒體,線上遊戲。

//TCP協議:TCP協議 可以看做是有確認機制的 UDP協議,更加安全可靠
TCP資料包:
資料傳送時將 TCP資料包 放入 IP資料包 的 DATA 中。
TCP資料包在理論上沒有長度限制,但為保證效率,它不會超過IP資料包的長度。
TCP應用場景:
Web Browsing,E-mail,檔案傳輸,線上遊戲。

//TCP協議為什麼更安全
SEQ:
TCP會把資料分成合適大小的多個包,並允許一次性發送多個包。
為方便接收時按順序還原,會給每個包編號(SEQ,資料包編號)。
假設:第一個包編號為1,負載200位元組,則第二個包編號為201。
ACK:
ACK中要攜帶:希望收到的下一個資料包的編號、接收方接收視窗的剩餘容量。
是否掉包(舉例):
主機A 向 主機B發包,主機B 成功接收1~4號包,5號尚未收到。
如果:後續 主機B 收到5號包,則回覆的ACK指向6號包。
如果:後續主機B仍未收到5號包,則回覆的ACK指向5號包。
若連續三次給主機A回覆的ACK指向5號包,則認為5號包掉包重發。
慢啟動:
伺服器發包的理想情況是,線上路允許的情況下達到最高速率。
為了得知對方線路的理想速率,TCP引入了慢啟動的概念。
首先慢速傳送,根據丟包情況和ACK返回的視窗容量調整發送速率。
如果對方接受不了就慢發(流量控制),如果網路擁堵就慢發(擁塞控制)。

//TCP的三次握手與四次揮手
三次握手:
所謂三次握手,就是建立一個TCP連線時,需要客戶端和服務端共傳送3個包以確認連線建立。
①. A向B傳送SYN(同步標識)、自己的SEQ(資料包編號),A進入SYN-SENT狀態。
②. B向A返回SYN(同步標識)、ACK(確認訊息)、自己的SEQ(資料包編號),B進入SYN-RCVD狀態。
③. A向B返回ACK(確認訊息)、自己的SEQ(資料包編號),B收到後檢查,檢查成功後雙雙ESTAB-LISHED。
四次揮手:
所謂四次揮手,就是斷開一個TCP連線時,需要客戶端和服務端共傳送4個包以確認連線斷開。
①. A向B傳送一個 FIN,表示自己不會再向B傳輸資料,A進入FIN_WAIT_1狀態。
②. B收到FIN後返回ACK給A,B進入CLOSE_WAIT狀態,A收到ACK後進入FIN_WAIT_2狀態。
③. B向A傳送一個FIN,表示自己不會再向A傳輸資料,B進入LASH_ACK狀態。
④. A收到FIN後返回ACK給B,A進入TIME_WAIT狀態,B收到ACK後進入CLOSED狀態,2MSL後A也CLOSED。

//SYN Flood攻擊:
DoS攻擊(拒絕服務攻擊)的一種,利用TCP協議缺陷,傳送大量偽造TCP請求使對方資源耗盡。
場景:假設第一次握手後客戶端宕機則無法接到第三次握手資訊。
正常情況:伺服器重試,等待一段時間後丟棄該連線,這個時段長度為 SYN Timeout。
SYN洪水攻擊:傳送大量半連線,使伺服器無暇理睬客戶正常請求,或直接堆疊溢位崩潰。
解決方案:縮短SYN Timeout、設定SYN Cookie、用DCN防火牆攔截。

//DNS
DNS是什麼:
可以把DNS(Domain Name System,域名系統)想象成一個巨大的電話本。
某臺伺服器在網路裡的真實地址是一個IP地址,但通常我們只知道域名。
DNS伺服器上會儲存“域名:IP”,通過DNS伺服器把域名翻譯成IP的過程就是域名解析(或叫DNS解析)。
域名層級:
大致結構:主機名.次級域名.頂級域名.根域名。
根域名:.root,所有域名的根域名是相同的,所以平時就省略了。
頂級域名(tld,top-level domain):如 .com .cn .net 等。
次級域名(sld,second-level domain):如 .baidu .sina 等,可自行註冊。
主機名(host):如 www 等,這是使用者在自己的域裡為伺服器分配的名稱。
域名解析流程:
客戶端主機:
①.根據輸入網址提取出域名,先查本機Hosts。
②.Hosts中有記錄就直接返回,沒有再向DNS伺服器發起請求(沒配DNS就完蛋)。
③.DNS伺服器沒回應瀏覽器會報錯:伺服器掛了、DNS的IP不對、被GFW攔截了。
④.DNS伺服器有迴應,就可以向其返回的IP地址發HTTP請求啦。
服務端主機:
①.首先訪問該伺服器,查詢其中是否有相應的快取,有就直接返回。
②.沒有快取,就傳送 根域名伺服器 的IP給我們,讓我們去那兒找。
③.根域名伺服器 裡如果還沒找到,就繼續給我們 頂級域名伺服器 的IP。
④.依次類推,直到得到正確的IP為止,這個過程也叫做“DNS遞迴查詢”。
安全問題:
域名劫持:
域名伺服器上儲存的域名記錄,被認為修改成錯的,這種情況就叫“域名劫持”。
場景:電信運營商(ISP)篡改自己的域名伺服器記錄。
辦法:改用靠譜DNS伺服器,向工信部投訴(400-881-0000),掛VPN或其他代理,全部強制HTTPS。
域名汙染:
從傳送DNS Query請求到有迴應的這段時間,攻擊者給我們返回假的應答,這種情況叫“域名汙染”。
場景:黨要求GFW(中國國家防火牆)全面封鎖外網,最簡單的辦法就是汙染該域名。

//CDN優化
同一個網址的服務可能分佈在多個伺服器,CDN(內容分發網路)能幫我們訪問最合適的伺服器。
使用者訪問網址,經過DNS解析後,將域名解析權交給CHAME指向的CDN專用的DNS伺服器。
第一次重定向:CDN的DNS伺服器將CDN的全域性負載均衡裝置的IP地址返給使用者。
第二次重定向:向CDN的全域性負載均衡裝置發起請求,該裝置經運算找到合適伺服器並返回其IP。

應用層:“應用層”是直接面向用戶的最高層,規定應用程式的資料格式,它的資料放在TCP的DATA部分。

//一次完整的HTTP請求過程
域名解析 - DNS分級查詢,把網址翻譯成IP地址。
建立TCP連線 - 3次握手,開啟客戶端與伺服器間的連線通道。
客戶端發起HTTP請求 - 傳送request,告訴服務端自己想要什麼。
服務端響應HTTP請求 - 傳送response,返回資料和狀態。
瀏覽器解析response中的HTML程式碼,並請求HTML中引用的資源(keep-alive的價值體現)。
瀏覽器對頁面進行渲染和呈現。

//HTTP報文
request
資料格式:
請求行 - 請求型別、請求的URL、請求使用的HTTP協議版本。
請求頭 - 伺服器要使用的附加資訊:User-Angent、Host等。
空行
請求體 - 可以使任何資料,可以在這裡傳引數。GET請求沒有請求體,POST請求有請求體。
請求型別:
GET - 完整請求一個資源
HEAD - 僅請求響應頭
POST - 向指定資源提交資料並請求處理
PUT - 用客戶端向伺服器傳送的資料取代指定文件
DELETE - 請求刪除伺服器上的指定文件
CONNECT - 讓伺服器代替使用者訪問其它網頁,並把資料傳回客戶端
OPTIONS - 請求伺服器告知其支援哪些功能
TRACE - 回顯伺服器收到的請求,用於測試和診斷
GET和POST的區別:
一個方法的本質是隻讀的,它就[安全] - GET、HEAD、OPTIONS、TRACE安全。
同一請求傳送多次效果相同,它就[冪等] - GET、HEAT、PUT、DELETE、OPTIONS、TRACE冪等。
另外:GET、HEAD可快取,POST有時可快取,但大多數瀏覽器未實現POST快取。
所以:GET - 請求獲取指定資源,它安全、冪等、可快取;POST - 根據請求對指定資源做處理,它不安全、不冪等、大部分瀏覽器中不可快取。
注意:HTTP協議沒有對GET和POST請求做出長度限制,只不過瀏覽器和web伺服器限制了URI的長度。
URL/URI/URN:
URI(統一資源識別符號) - 在某一規則下把一個資源獨一無二的標識出來。
URL(統一資源定位符)- 用定位的方式實現的URI。
URN(統一資源名稱)- 用名稱的方式實現的URI。
常見請求頭:
Accept - 告訴伺服器,自己可以接收哪些MIME型別
Accept-Encoding - 告訴伺服器,自己支援哪些壓縮方式的檔案
Accept-Language - 告訴伺服器,自己支援哪些語言
Connection - 告訴伺服器,自己支援keep-alive特性
Cookie - 每次請求都帶上 cookie 方便伺服器識別是否是同一客戶端
HOST - 用來標識請求伺服器上的哪個虛擬主機
User-Agent - 使用者代理,一般情況下是瀏覽器
response
資料格式:
狀態行 - HTTP協議版本、狀態碼、狀態訊息
訊息頭 - 客戶端要使用的附加資訊
空行
響應正文 - HTML等返回的正文
常見狀態碼:
1xx - 指示資訊,表示已經收到,要繼續處理
2xx - 成功
200 - OK,請求成功
3xx - 重定向
301 - Permanently Moved,永久重定向
302 - Temporarily Moved,臨時重定向
304 - Not Modified,未修改(直接訪問本地)
4xx - 客戶端錯誤
400 - Bad Request,客戶端請求有語法錯誤
401 - Unauthorized,請求未經授權
403 - Forbidden,服務端拒絕提供服務
404 - Not Found,資源不存在
5xx - 服務端錯誤
500 - Internet Server Error,伺服器內部錯誤
502 - Bad Gateway,代理伺服器聯絡不到後端伺服器
504 - Gateway Timeout,後端伺服器響應超時
常見響應頭:
Connection - 使用keep-alive屬性
Content-Type - 返回內容的MIME型別
Content-Encoding - web伺服器支援的返回內容壓縮編碼型別
Date - 原始伺服器訊息發出時間
Last-Modified - 請求資源的最後修改時間
Server - web伺服器軟體名稱
MIME型別:
MIME(Multipurpose Internet Mail Extensions)是描述訊息內容型別的一種標準。
MIME訊息能包含文字、影象、音訊、視訊等應用程式支援的資料型別。
HTTP請求規定,頭資訊是ASCII碼,但後面資料可以是任何格式(HTTP/2開始就不是了)。
在request和response裡寫他們支援的MIME型別,是為了明確雙方能解析什麼。

//HTTP協議版本演進
HTTP/0.9
規定了GET請求,且只能響應HTML格式字串(已淘汰)。
HTTP/1.0
加入了HEAD和POST請求,增加頭資訊,且能響應任何形式的資料。
缺點:每個TCP連線只能傳送一個請求。
由於,TCP連線建立的成本很高,需要三次握手、慢啟動、初始傳送速率較差。
並且,在response得到HTML並解析,解析完成後需要請求HTML裡引用的資源。
因此,有些瀏覽器加入非標準屬性:Connection:keep-alive,要求伺服器不關閉TCP連線。
這個屬性在HTTP/1.0中未被標準化,在瀏覽器間的表現可能不一致,不能根本解決問題。
HTTP/1.1
加入了PUT、PATCH、OPTIONS、DELETE請求。
頭資訊增加HOST欄位,用來指明伺服器域名,使我們可以向統一主機上的不同網站傳送請求(虛擬主機)。
持久連線:
HTTP/1.1中將 Connection:keep-alive 標準化了,不寫宣告也能使TCP保持長連線。
非標準做法 - 客戶端或服務端發現對方一段時間內沒有活動,就主動關閉TCP連線。
標準做法 - 客戶端在最後一個請求時傳送:Connection:close,要求關閉TCP連線。
目前,針對同一個域名,大多數瀏覽器允許同時建立6個持久連線。
管道機制:
HTTP/1.1中允許客戶端同時傳送多個請求,然後伺服器按順序迴應。
且,要在response中加入Content-Length欄位,讓客戶端知道下一個迴應從哪開始。
分塊傳輸編碼:
HTTP/1.1規定了 Transfer-Encoding:chunked欄位。
使用Content-Length欄位,需要在伺服器迴應前把所有資料生成,以便知道長度。
該欄位表示迴應欄位由數量未定的資料塊組成,使伺服器可以生成一點兒傳送一點兒。
每個非空資料塊前有一個16進位制值,表示該資料塊長度,直到標識為0就表示傳送完了。
利用這個欄位,可以避免耗時過長的操作阻塞response。
痛點:
同一TCP連線中允許多次請求,但服務端需要按順序迴應,容易出現“隊頭阻塞”。
解決方案:減少請求數、多開持久連線。
前端做法:合併指令碼、合併樣式表、將圖片遷入CSS程式碼、域名分片。
HTTP/2
HTTP/2 可以說是理想主義了,如果該協議普及了,很多前端的優化手段就用不著了。
二進位制協議:
我們知道計算機只能識別二進位制數,所以二進位制解析起來比文字簡單省時。
HTTP/1.1中,頭資訊是文字(ASCII碼),資料體可以是文字或二進位制。
HTTP/2中,頭資訊和資料體均為二進位制,分別交頭資訊幀和資料幀,且允許定義額外幀。
多工通訊:
多工表示雙向實時通訊
HTTP/1.1中,客戶端可同時傳送多個請求,但服務端要按順序一一回應
HTTP/2中,客戶端和服務端可同時傳送多個請求或迴應,避免“隊頭阻塞”
資料流:
每個請求或迴應的所有資料包的集合叫一個數據流,每個資料流都有唯一的編號。
資料包不按順序傳送,為方便拼裝要為每個資料包做標記並攜帶資料流編號。
客戶端資料流編號為奇數,服務端資料流編號為偶數。
資料流傳送到一半可以取消,客戶端可以指定資料流優先順序,優先順序越高的越早得到迴應。
頭壓縮:
HTTP是無狀態協議,每次請求都要附上所有資訊,其中很多欄位重複,浪費頻寬。
HTTP/2允許頭資訊使用gzip或compress方式壓縮後再發送。
HTTP/2允許客戶端和服務端共同維護一張頭資訊表,為每個欄位編號,之後用編號代替欄位。
伺服器推送:
HTTP/2允許在未經請求的情況下,主動向客戶端傳送資源。
HTTP/2可以對頁面中請求的靜態資源進行預知,並將其與網頁一同推送給客戶端。

//HTTPS
對稱加密和非對稱加密:
加密就是讓明文變成密文,解密就是讓密文變成明文。
加解密的過程都需要一個叫 祕鑰 的東西參與, 祕鑰 可以看做是一個密碼本。
對稱加密  - 加密和解密用同樣的祕鑰。
非對稱加密  - 加密和解密用不同的祕鑰,公鑰 加密過的東西,只有用對應的 私鑰 才能解密。
其中,對稱加密 速度快但安全性低,非對稱加密 速度慢但安全性高。
證書體系(場景舉例):
說人話版本:
原始介紹信 - A公司的甲要去拜訪X公司,需要攜帶有A公司公章的介紹信,證明自己來自A公司。
原始介紹信痛點 - 與X公司有業務往來的公司很多,X公司可能無法分別識別他們各自的公章。
升級介紹信 - 我們找到權威的Y公司,給甲開一封帶有Y公司公章和A公司公章的介紹信。
升級介紹信思路 - 甲拿著兩封信到X公司,X處只要認識Y的公章,再比較兩封信中X的公章是否相同。
翻譯成技術語言:
證書 就是 原始介紹信 ,CA 就是Y公司,CA證書 就是 升級介紹信。
證書信任鏈 - CA證書 信任了 證書,這種信任關係可以巢狀,上層節點可信,則預設下層均可信。
SSL/TLS協議:
Netspace發明了SSL協議,SSL協議被標準化後改名叫TLS協議。
可以把他們理解成同一個協議的不同階段,也可直接寫做SSL/TLS協議。
基本思路:
非對稱加密 - 客向服索要公鑰,客用公鑰加密後把密文發給服,服用自己保管的私鑰解密 。
如何保證公鑰不被篡改 - 把公鑰放在CA證書裡,只要證書可信,公鑰就可信。
如何提高效率 - 針對每次對話生成 session key,用session key加密資訊,用公鑰加密 session key。
基本流程:
客戶端請求 - 傳送:加密協議版本、支援的加密演算法、支援的壓縮演算法、一個隨機數。
服務端迴應 - 傳送:確認加密協議版本、確認使用的加密方法、伺服器證書、一個隨機數。
客戶端迴應 - 驗證服務端證書通過後傳送:編碼變動通知、一個隨機數、客戶端握手結束通知。
服務端迴應 - 用以上的三個隨機數匯出session key後傳送:編碼變動通知、伺服器握手結束通知。
三個隨機數:
SSL協議中證書是靜止的,隨機數可以保證祕鑰隨機,客和服都要生成隨機數才能保證每次祕鑰不同。
SSL協議不相信每個主機能產生完全隨機的數字,所以要加最後一個隨機數(pre-master key)保證隨機性。
HTTPS原理:
HTTP協議是明文的,存在“被竊聽、被篡改、被冒充”的風險;
HTTPS可以看做是 HTTP over SSL/TLS。
即在TCP連線開啟後,再開啟SSL/TLS加密通道(傳輸層),讓HTTP在加密通道中傳輸。
在加密通道中傳輸的就是正常的HTTP請求,只不過傳送的內容通過 session key 加密過。
SSL/TLS協議也可以搭配給更多的應用層協議,如:FTP、SMTP、POP、Telnet等,和HTTPS原理相同。