## 前言 在網際網路高速發展的今天,我們通過手機,電腦等通訊裝置可以很輕鬆達到`未出茅廬便知天下事`的境界。每天我們都要訪問數不勝數的網站,通過開啟瀏覽器,輸入網址兩步搞定。當然更為常規的做法是開啟瀏覽器,設定首頁為某個搜尋引擎網站(如百度,谷歌),在搜尋框中輸入想要訪問的關鍵詞,幾秒的功夫一個個網站就呈現在客官眼前任由客觀挑選。但,,,你有沒有想過為什麼只是輸了個網址怎麼頁面就呈現出來了呢? ![preword.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af950ffc60bba?w=500&h=341&f=jpeg&s=133772) ## 初探計算機網路 ### 網路 網路的概念是指一組具有通訊功能的裝置相互連線形成的。什麼叫具有通訊功能的裝置呢?這個可以分為主機,如電腦、手機等;以及連線裝置如路由器,交換機,調變解調器等。此時這些連線裝置對於你來說可能只是個抽象的名詞,不過沒關係,之後我都會一一講到,請耐心地看下去。 ### 區域網,廣域網,網際網路絡 區域網(LAN),通常是私有的,用於連線一個辦公室,一棟教學樓,一個工作室等等。 如下圖,處於同一個區域網的使用者A,B。A可以聯絡到B,但卻不能聯絡到處於另一個區域網的C。 ![image1.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af950fdd09cea?w=1296&h=535&f=jpeg&s=37750) 廣域網(WAN),廣域網相比於區域網,有著更大的地理覆蓋範圍。可以覆蓋一個城市,一個省,一個國家,甚至全世界。 如下圖,廣域網由一個個子網路連線而成,並且廣域網中的子網路之間可以正常通訊。 ![image2.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af951025a88b1?w=1306&h=508&f=jpeg&s=41435) 網際網路絡,幾乎不存在孤立的區域網或廣域網,它們都相互連線在一起。當兩個或多個網路連線起來,就形成了一個網際網路絡。 ![internet.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95102a6bbee?w=899&h=142&f=png&s=58540) ### 資訊交換 由圖1,圖2我們很容易產生網路之間和同一網路下的使用者之間的通訊方式是一樣的錯覺。所以看到圖3很疑惑欸,箭頭沒有了,虛線來了,路由器和交換機也來了。。別忙著揍我,先聽我解釋。 #### 電路交換網路 兩個終端之間始終保持一條專用連線,由交換機進行轉發。由圖可以發現連線兩個子網的線路更“粗”,這是因為每個終端都需要一個專用連線,所以線路的頻寬更大,也就更“粗”了。 ![circuit-switched.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951043c04c5?w=663&h=225&f=png&s=84109) #### 分組交換網路 同一個子網路的終端之間依然保持一條專用連線,但子網間的通訊不再為所有的終端建立專用連線,而是一個固定大小的線路,每個訊息根據到達先後順序排隊,每次取不大於線路頻寬的訊息進行轉發。細心的同學會發現上圖的交換機這裡變成了路由器,其實路由器也擁有交換機資訊轉發的功能,但除此之外還增加了一個網路層用於IP定址。這是網路間通訊的關鍵,之後會在網路層中詳細講解。 ![router-switch.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95105cf8733?w=686&h=259&f=png&s=71892) #### 為什麼資訊交換中既用交換機又用路由器 如圖3,既使用了電路交換網路,又使用了分組交換網路。之前談到過,路由器比交換機多了一個網路層,因此進行資料轉發時花費的時間更多,使用交換機進行子網內部資料轉發更加合適。而子網間通訊之所以更多選取分組交換網路,是因為雖然分組交換需要排隊會帶來一些時延,但比電路交換成本更加低廉,資源利用率也更高。 ### 網路分層 #### 為什麼要分層??這裡是一個例子 假如夏爾和慕恩是一對高三小情侶,為了防止親密的資訊被父母看到,他們決定對會話進行加密,享受美好的二人時光。 ![example1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95186a7698a?w=963&h=702&f=png&s=56086) 從以上可以看出,夏爾和慕恩之間的通訊從上到下分為三層,第一層負責讀/寫訊息,第二層負責加密/解密訊息,第三次層責傳送/接收。每一層相互對應,層與層之間互不干擾,每層都做自己分內的事。 #### TCP/IP協議簇 ![tcp_cen.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95187214cf2?w=998&h=425&f=png&s=145498) 網路傳輸也採用這個思想,將複雜的傳輸過程,分為一個個層次模組。模組內部接收上一層傳遞的資訊然後進行處理,處理結束後呈遞到下一層。 這裡說一下為什麼路由器接收和傳送不使用同一個鏈路。因為雖然路由器有同一個網路層,但它涉及到n個鏈路和物理層協議的任意組合,路由器接收基於一對協議的鏈路1再把它投遞到基於另一對協議的鏈路2。而交換機雖然含兩層,但兩層在同一個協議集中。 關於各層次的功能特點會在之後的內容中詳細介紹。 ## 應用層 ### 從一個例子說起 眼看情人節到了,夏爾少爺成功熬過12點,準點傳送了情人節快樂的訊息。訊息經應用處理為報文通過下面幾層網路成功傳遞到慕恩那裡。慕恩開心地看著手機發呆。。。 ![image2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951a67c6d56?w=814&h=549&f=png&s=40665) ### 你說的太簡單了,我需要更多的力量(知識) #### 程序通訊 兩個終端間的通訊本質上是終端作業系統中程序之間的通訊。 兩個不同系統中的程序,通過計算機網路交換報文而相互通訊。 作業系統中的程序是CPU資源分配的最小單位,一個程序可以被認為是執行終端系統中的一個程式。 ![image.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c55f9d07?w=693&h=532&f=png&s=12735) 上圖是一個終端間程序通訊的簡單示意圖。我們可以把程序比作一個房子,socket就像房子的大門,報文通過大門經傳輸層-網路層-資料鏈路層-物理層傳輸到目的地。再自下而上地去掉各層首部。 #### 報文 在圖8所示的流程中,應用層所關心的只有一個,那就是報文。應用層協議定義了執行在不同端系統上的應用程序如何相互傳遞報文。應用層協議定義了: 1. 報文的型別(響應報文/請求報文)。 2. 報文型別的語法(如HTTP協議中請求報文首行是請求方法,請求地址,協議;而響應報文首行是協議,狀態碼,描述)。 3. 欄位的語義(欄位對應的資訊含義)。 4. 一個程序何時以及如何傳送報文,對報文進行響應的規則。 ### 你所應當瞭解的應用層協議 #### 如何讓報文攜帶協議資訊呢 很容易想到可以讓報文攜帶協議的標記欄位,然後到達目的地後再檢查該欄位。那麼具體如何實現呢?其實只需要將協議標識的首部欄位加在報文的首部,然後隨報文傳送而傳送。檢測的話,取下首部欄位,按協議要求將資料報文傳送給首部欄位對應的socket即可。 #### http協議 ![http.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951b6218fe2?w=548&h=328&f=png&s=60859) ##### 定義: 超文字傳輸協議,是一個客戶端和伺服器端請求和應答的標準(TCP),用於從WWW伺服器傳輸超文字到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網路傳輸減少。簡單來說http協議起到了一個讓你點選網站後能得到頁面反饋的作用。 ##### http1.0 在http早期,每個http請求都要求開啟一個tcp socket連線,並且使用一次之後就斷開這個tcp連線。 ##### http1.1 http1.1可以使用keep-alive可以改善這種狀態,即在一次TCP連線中可以持續傳送多份資料而不會斷開連線。通過使用keep-alive機制,可以減少tcp連線建立次數,也意味著可以減少TIME_WAIT狀態連線,以此提高效能和提高httpd伺服器的吞吐率。但是keep-alive timeout時間也不是越長越好,長時間的tcp連線容易導致系統資源無效佔用,因此設定合理的keep-alive timeout時間很重要 ##### http2.0 1. 多路複用。建立一個tcp連線,一個連線上有任意多個流,報文訊息分割為一個幀或多個幀在位元組流裡面併發傳輸,值得注意的是同一報文的若干幀必須在同一位元組流上進行傳播。等待報文幀傳輸完成後再進行訊息重組。 2. 二進位制分幀。將傳輸的報文劃分為首部和訊息負載兩個幀,並採用二進位制編碼。 3. 首部壓縮:客戶端與服務端維護一份相同的靜態字典,裡面儲存了常用請求頭的名稱和值,對於字典中只有名稱沒有值的首部,在傳輸時需要先索引其值在用哈夫曼編碼減少體積,客戶端和服務端還會維護一個動態字典用於存放請求用到的頭部,後續傳播就可以只傳索引, 4. 伺服器推送:服務端可以主動向客戶端推送資源。 ##### http和https的區別 1. http是超文字傳輸協議,資訊是明文傳輸,https則是具有安全性的ssl加密傳輸協議。 2. http的連線很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比http協議安全。 3. https協議需要ca證書,費用較高。 4. 使用不同的連結方式,埠也不同,一般而言,http協議的埠為80,https的埠為443 ##### 證書驗證 瀏覽器使用內建的根證書中的公鑰來對收到的證書進行認證,如果一致,就表示該安全證書是由可信任的頒證機構簽發的,這個網站就是安全可靠的;如果該SSL證書不是根伺服器簽發的,瀏覽器就會自動檢查上一級的發證機構,直到找到相應的根證書頒發機構,如果該根證書頒發機構是可信的,這個網站的SSL證 書也是可信的。 ##### ssl握手過程 1. 客戶端向服務端發出加密通訊的請求。這被叫做clientHello請求, - 包括支援的協議版本,一個隨機數用於等會生成會話金鑰,支援的加密方法,支援的壓縮方法 2. 迴應,serverhello, - 確認加密通訊協議的版本,一個隨機數用於稍後生成會話金鑰,確定加密方法,伺服器的證書 3. 客戶端驗證服務端證書是否為可信機構頒步,如果不可信會給訪問者一個警告有起決定是否繼續通訊, - 返回一個隨機數用於公鑰加密,編碼改變通知(之後的資訊都用雙方商定的加密方法和金鑰發生),客戶端握手結束的通知 4. 服務端收到客戶端的第三個隨機數後,計算生成本次會話用的“會話金鑰”,然後向客戶端傳送下面資訊: - 編碼改變通知,表示隨後的資訊都將用雙方商定的加密方法和金鑰傳送。伺服器握手結束通知,表示伺服器的握手階段已經結束。這一項同時也是前面傳送的所有內容的hash值,用來供客戶端校驗。 http協議實在太重要,涉及到的知識點比較多,這裡只是淺嘗輒止。之後會單開一篇文章專門講http協議,當然這裡推薦三元大佬寫的文章[HTTP靈魂之問,鞏固你的 HTTP 知識體系](https://juejin.im/post/5e76bd516fb9a07cce750746). ##### 為什麼ssl證書有過期時間 最重要的原因在於吊銷。當網站丟失了私鑰後,應該向證書頒發機構(ca)申請將其證書放入吊銷列表。如果證書永久有效,吊銷列表越來越大,會給瀏覽器和ca機構增加很大的流量壓力。而如果有過期時間,那麼ca可以剔除過期的網站,瀏覽器也不信任過期的證書。 #### ftp ![ftp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c61cc131?w=734&h=382&f=png&s=65593) 如上圖,ftp協議作為一個檔案傳輸協議,它的基本流程如下: 1. 使用者提供遠端伺服器上註冊的uid和password進行使用者認證,認證成功後建立TCP連線。 2. 使用者通過ftp使用者介面從本地的檔案系統中上傳檔案經TCP連線到達遠TCP端伺服器。 3. 遠端伺服器將檔案寫入遠端檔案系統,至此一個檔案上傳到遠端伺服器的工作完成。 ##### 與http協議的異同 ftp和http都是檔案傳輸協議,並且傳輸層都基於TCP協議。 而他們最顯著的區別在於ftp協議使用了兩個並行的TCP連線(控制連線和資料連線)來保證資料的傳輸。控制連線主要用於上述提到的使用者認證以及檔案存取標識(也就是標識當前是讀取檔案還是存放檔案)等;資料連線用於傳輸檔案資料。 http預設埠是80;ftp預設埠是20和21 ![ftp2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9520a571ee1?w=628&h=158&f=png&s=37866) #### dns dns是一個域名解析協議,通常會配合其他應用層協議完成相應的需求。在談dns之間需要先明確幾個概念,分別是域名,ip地址,使用者主機地址(mac地址)。 ##### 域名 域名可以被近似地看作ip地址的別名,簡單來說就是你每天看到的各種網站。有一個形象的比喻是:ip地址就像你的身份證號,而域名就像你的名字一樣,名字比身份證號更容易記憶。但有所不同的是域名不會發生重名的情況(想想為什麼不能)。 ##### ip地址 主機的主機板上有一塊名為網絡卡的硬體,它內部考錄了mac地址,用於標識一臺主機的實體地址。但由於不同廠商指定的標準不同,mac地址的編址方式也是千奇百怪。這是有人提出:建立一個邏輯層,用虛擬的ip地址對映真實的mac地址,再將ip地址的編址方式制定為一個全球通用的標準就行了。因此ip地址實際上是一個邏輯上的地址,但我們暫時不用關注ip地址和mac地址如何對映的,將ip地址視為電腦主機的網路地址標識即可。 ##### mac地址 主機的實體地址,用於唯一標識一臺主機的。當然一臺主機不一定只有一個網絡卡,比如膝上型電腦通常含一個有線網絡卡和一個無線網絡卡。 ##### dns解析流程 其實最早的域名解析是採用本地檔案hosts檔案進行解析的,但隨著網際網路網站越來越多,顯然用檔案解析的方式不符合這樣的需求。steam玩家對此應該不陌生: ![hosts.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9520d4a1585?w=507&h=268&f=png&s=18350) 一個域名的解析順序如下: ![dns1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952216448a8?w=553&h=406&f=png&s=15688) 如果夏爾的域名是 **ciel.jialidun.edu**,慕恩的域名是**moon.nannvnan.edu**,那麼夏爾的主機是怎麼獲取慕恩的ip呢? ![dns2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95237d2af0e?w=528&h=599&f=png&s=89246) emmm,是不是跟想象中的有點不一樣呢,接下來聽我一一道來。首先弄清楚上圖中各個dns伺服器到底有怎樣的職責。 ##### dns分散式結構 dns伺服器大體上可分為根伺服器,頂級域伺服器,權威伺服器。 1. 根伺服器類似於樹的根部,屬於dns伺服器的頂層,多數部署在北美洲。 2. 頂級域伺服器,常見的 `com cn edu org ` ,比如代表國家的`cn uk ca` 等。 3. 權威伺服器,在因特網上具有公共可訪問的主機。如學校,大型公司等機構。 ![dns3.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952441eb7a3?w=956&h=369&f=png&s=188018) 那麼之前的流程就很好解釋了,夏爾傳送了域名解析請求,其中包括源域名和目標域名。 1. 本地權威伺服器會接收到該請求並檢視目標域名是否是自己的管轄區域,如果不是它將把該請求轉發給根伺服器。 2. 根伺服器會查詢目標域名的頂級域(如這裡的`edu`),然後將分管該頂級域的頂級域伺服器ip發給本地伺服器,本地伺服器再向頂級域伺服器轉發請求。 3. 頂級域伺服器收到請求後會查詢該域名屬於哪個權威伺服器管轄,然後將查詢結果返回給本地伺服器。 4. 本地伺服器將請求轉發給目標伺服器,目標伺服器再根據域名查詢相應的ip地址再將結果返回給本地伺服器。 5. 本地伺服器將目標域名的ip返回給夏爾的主機。 但是實際上dns查詢可能並不會完全遵守上述流程,試想每天有上億人訪問谷歌百度等,如果每個人的訪問都要經歷這樣冗長的流程,對於使用者體驗和伺服器效能來說是災難性的。而解決方案則是使用一個快取的機制,將使用者訪問過的網站ip地址進行快取,查詢時直接從快取中取。這裡只是簡單談談,更多的細節會在http協議中詳細講解。 ##### 應用層協議對應傳輸層協議 | 應用層協議 | 傳輸層協議 | 應用 | | :--------: | :--------: | :----------: | | HTTP | TCP | Web | | FTP | TCP | 檔案傳輸 | | DNS | TCP/UDP | 域名解析 | | SMTP | TCP | 電子郵件 | | Telnet | TCP | 遠端終端訪問 | | RIP | UDP | 路由選擇協議 | ##### DNS何時用TCP協議,何時用UDP協議 1. DNS在進行區域傳輸的時候使用TCP協議,其它時候則使用UDP協議; DNS的規範規定了2種類型的DNS伺服器,一個叫主DNS伺服器,一個叫輔助DNS伺服器。在一個區中主DNS伺服器從自己本機的資料檔案中讀取該區的DNS資料資訊,而輔助DNS伺服器則從區的主DNS伺服器中讀取該區的DNS資料資訊。當一個輔助DNS伺服器啟動時,它需要與主DNS伺服器通訊,並載入資料資訊,這就叫做區傳送(zone transfer)。 2. UDP報文的最大長度為512位元組,而TCP則允許報文長度超過512位元組。**當DNS查詢超過512位元組時,協議的TC標誌出現刪除標誌**,這時則使用TCP傳送。通常傳統的UDP報文一般不會大於512位元組。 因此在區傳送中使用TCP協議。 ## 傳輸層 ### 從另一個例子講起 一天,夏爾學習到很晚肚子餓了,於是他熟練地開啟美團,點了一份炸雞套餐。不一會兒外賣小哥就將一份香噴噴的炸雞送到夏爾的快樂椅前了。。。 ![kfc.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95263ecef21?w=675&h=562&f=png&s=54611) 從之前的知識我們可以猜想到`我想吃脆皮炸雞`這段報文是由應用層協議負責的。那麼報文資訊的傳遞是怎麼實現的呢?從上圖可以看出夏爾與肯德基之間彷彿通過美團外賣在邏輯上建立了連線,但將炸雞送到夏爾家確實由外賣員在物理層面建立的連線。說到這裡是不是有點感覺了呢,傳輸層的作用就是在兩個終端之間建立邏輯連線,而網路層的作用則是實打實地建立了兩個終端地址的連線。(之前有提到網路層其實也是抽象的邏輯連線,這個問題先按下不表,之後網路層會有所解答) #### 為什麼需要邏輯連線(傳輸層)呢 根據之前的知識我們知道路由器中最頂層的是網路層,也就是說分組交換中根本用不到傳輸層,那麼費盡周折地弄一個傳輸層有什麼意義呢?我們知道微信可以視訊聊天,可以語音聊天,可以文字聊天。那麼假如夏爾和慕恩有特殊癖好(視訊聊天的同時打字聊天),夏爾和慕恩的ip地址都是暫時固定的,那麼文字流和視訊流都會在這兩個ip地址間進行傳遞。那麼問題來了,我們知道視訊聊天服務和文字聊天服務肯定是兩個會話服務,那麼怎麼將文字流交給文字會話,視訊流交給視訊會話呢?本著遇事不決量子力學的態度,我們大膽猜想可以在報文上加標記,這就是傳輸層所著手解決的一個問題,當然傳輸層的作用還不止這些。 #### 傳輸層怎麼實現端到端會話傳輸的呢 ##### 多路分解和多路複用 ![image.png](https://user-gold-cdn.xitu.io/2020/4/25/171af951c55f9d07?w=693&h=532&f=png&s=12735) 不知道大家對這張圖還沒有印象,之前提到過報文由應用程式程序通過socket呈遞給傳輸層到站後再通過傳輸層分發到相應socket由另一個終端的應用程式接收。我們可以近似地把程序理解為會話,而socket是程序與傳輸層之間的橋樑。 多路分解:將運輸層報文段中的資料交付到正確的套接字(socket)。 多路複用:在源主機從不同套接字中收集資料塊,並未每個資料塊裝上首部資訊(標記)從而生成報文段,然後將報文段傳遞到網路層。 值得一提的是多路分解和多路複用並不是傳輸層所特有的,它們是所有計算機網路都需要的。 ##### 埠 瞭解了多路分解和多路複用後,我們知道套接字應該是具有唯一標識的橋樑,同時它還要告知行人這座橋通向何處。這就引申出了埠這個概念,埠分為源埠號(從哪來)和目的埠號(到哪裡去)。報文分別用了16個位元位標識源埠和目的埠,也就是說埠的範圍在0-65535之間。同時0-1023埠是受限制的(被一些很重要的諸如http協議等使用了)。之前提到過http協議預設佔用80埠,你可以試試下面連結跟你平時看到的度娘相比有什麼不同。[http://www.baidu.com:80](http://www.baidu.com:80) ### 傳輸層雙雄 #### UDP和TCP的區別 1. tcp是面向連線的,udp是無連線的 2. tcp提供可靠互動,報文傳輸無差錯,不丟失,不重複地按序到達,而udp是儘可能地實現互動,即提供不可靠互動 3. tcp是面向位元組流,udp面向報文。應用層一次傳送給tcp一個數據塊,tcp將其視為無結構位元組流,tcp中有一個快取,當應用程式資料塊太長tcp會將其劃分為更小的塊傳輸。而udp則無論應用層傳送多大的報文都會照樣直接傳送,因此應用層必須選擇合適的報文大小,太長ip層需要分片,降低效率;太短,ip太小。 4. tcp支援1對1的互動,udp支援1對1,1對多,多對多的互動 5. tcp首部為20個位元組,udp首部只佔8位元組 6. 檔案,郵件用tcp,視訊用udp 因為雙雄各有千秋,所以有各自適應的場景。總的來說udp無論是首部開銷還是無連線的特點都使得其速度比tcp快,但在可靠互動,流量控制和擁塞處理這方面tcp顯然是更好的一方。 ### UDP #### 報文結構 ![udp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95267c8f852?w=339&h=309&f=png&s=90351) ##### 源埠號,目的埠號 目的埠號是為了報文到站後尋找合適的socket,那麼為什麼要把源埠號也帶上呢?因為連線是全雙工模式,也就是說接收方既是傳送方也是接收方,當接收方想反饋資訊給傳送方時只需要從報文中獲取源埠號作為反饋報文的目的埠號即可。 ##### 長度 一組報文的長度,用於分割報文組同時檢測是否出現丟包現象。 ##### 校驗和 16位元位,用於檢驗報文是否在傳送過程中受外界干擾出現了位元改變的情況。(我們知道資料最終是由電纜或光纜或電磁波傳遞的,物理學上外界環境可能會影響這些訊號,比如使得高電平變為低電平對應到位元位就是將1變為了0) 校驗原理: 1. 將udp報文中的所有16位位元字進行相加 2. 將位元字相加的結果轉換為其反碼(如果有溢位,它要被回捲),作為其檢驗和 3. 接收方將所有16位位元字相加(包括檢驗和),檢視結果是否為1111111111111111 ``` //假定,udp首部有這三個16位位元 0110011001100000 0101010101010101 1000111100001100 0110011001100000 + 0101010101010101 = 1000111100001100 + 1000111100001100 = 0100101011000010 (這裡產生了溢位將進行回捲,所謂回捲是指捨棄高位進位而在最低位+1) 反碼運算是將0 => 1; 1 => 0。 0100101011000010 => 1011010100111101 //接收方 之前三個16位元 + 檢驗和 原碼 + 補碼 = 1111(原始碼位數個1) 所以如果不為1111111111111111,那麼資料在傳輸過程中一定傳送了位元變化。 ``` #### udp的特性 1. udp是無連線的。也就是說使用udp協議傳輸報文,不需要事先建立一條資訊通道,而是新增首部後直接交給網路層 2. udp提供不可靠互動。之前講解udp報文欄位時我們看到了雖然udp提供了差錯檢測的功能,但它卻對差錯回覆無能為力。也就是說當udp接收到受損的報文時,只能將其丟棄。(也就是視訊中存在的丟幀現象) 3. 面向報文。為報文新增首部後,直接交給網路層進行傳遞。 4. 1對1,1對多。因為不需要建立通道,所以可以實現類似網路層廣播的一個效果。 ### TCP #### 報文結構 ![tcp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952c092d75a?w=543&h=514&f=png&s=201648) ##### 序號和確認號 用於建立連線(建立傳輸通道),斷開連線。同時也是實現可靠資料傳輸的關鍵,之後會更多地討論。 ##### 首部長度和保留未用 TCP首部的長度是可變的,首部長度欄位用於將首部與資料欄位區分開。保留未用如其名,為保留欄位。 ##### URG,ACK,PSH,RST,SYN,FIN 各佔一個位元位。ACK位元用於指示欄位中的值是有效的,RST,SYN和FIN用於建立和斷開連線,URG用於標記報文段是否為“緊急”的資料,PSH被置1時,接收方應該立即將資料交給上傳。(實踐中,PSH,URG並沒有使用) ##### 緊急資料指標 指向緊急資料尾部的指標,與URG配合使用。(實踐中並沒有用到) ##### 接收視窗 用於流量控制,之後會詳細地講解。 ##### 選項 通常為空,該欄位用於傳送方與接收方協商最大報文欄位長度時,或在告訴網路環境下用作視窗調節因子時使用。 #### 建立連線 ##### 三次握手 ![3](https://user-gold-cdn.xitu.io/2020/4/25/171af952cdcad130?w=1364&h=768&f=gif&s=111217) 1. 客戶端傳送一個syn=1連線請求和一個序列號seq=x,然後客戶端進入syn_send狀態,等待伺服器的確認 2. 伺服器收到客戶端的syn請求,需要對syn進行確認於是將ack=x+1,然後將序列號seq=y;最後將上述資訊放到一個報文段中傳送給客戶端,伺服器進入syn_receive狀態 3. 客戶端收到服務端的確認資訊,ack=y+1,seq=x+1,向服務端傳送ack確認報文。該報文傳送完畢後連線建立完成。 ##### 為什麼要三次握手 主要是為了防止已經失效的請求報文段突然又傳送到了服務端造成錯誤。舉個例子,客戶端向服務端傳送的連線請求報文因網路原因超時,延期很久後到達服務端。服務端收到該連線請求認為是一次新的連線就像客戶端傳送連線確認請求,但因為該連線報文早已失效,客戶端並不會響應服務端的確認資訊。不過沒有三次握手,服務端會認為連線已經完成,一直等待客戶端傳送資料,這樣服務端的很多資源就浪費了。 ##### SYN洪泛攻擊: - SYN攻擊就是Client在短時間內偽造大量不存在的IP地址,並向Server不斷地傳送SYN包,Server則回覆確認包,並等待Client確認,由於源地址不存在,因此Server需要不斷重發直至超時,這些偽造的SYN包將長時間佔用未連線佇列,導致正常的SYN請求因為佇列滿而被丟棄,從而引起網路擁塞甚至系統癱瘓。 - 防範SYN攻擊措施:降低主機的等待時間使主機儘快的釋放半連線的佔用,短時間受到某IP的重複SYN則丟棄後續請求。 ##### 四次揮手 ![4.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952d4dc1a00?w=682&h=384&f=gif&s=107271) 1. 客戶端傳送一個fin=1連線關閉的請求,序號seq=u,客戶端的進入fin_wait_1狀態 2. 服務端收到連線釋放報文段後即發出確認報文段,(ACK=1,確認號ack=u+1,序號seq=v),客戶端進入fin_wait_2狀態 3. 服務端向客戶端傳送FIN報文段,請求關閉連線,同時主機2進入LAST_ACK狀態(FIN=1,ACK=1,序號seq=w,確認號ack=u+1) 4. 客戶端收到服務端的fin報文,向客戶端傳送ack報文然後進入time_wait狀態。服務端收到報文後關閉連線。客戶端等待兩個msl時間後關閉連線(ACK=1,seq=u+1,ack=w+1) ##### 為什麼四次揮手 因為tcp是全雙工模式,當主機1傳送fin報文表示主機1沒有資料要傳送了,主機2收到該報文傳送一個ack確認報文表示我知道主機沒有要傳送的資料了,但主機1還可以接收報文,主機2傳送一個fin到主機1,主機1收到後表示我知道主機2也沒有資料要傳送了。然後雙方再愉快的分手 ##### 為什麼等待2msl 1. 保證tcp的全雙工連線能正常關閉。如果客戶端直接關閉,那麼ack報文可能因為網路問題導致服務端沒有收到客戶端的ack確認請求。那麼服務端會重新發送fin報文但此時客戶端已經關閉該連線因此找不到與服務端對應的連線。 2. 保證此次連線的資料段從網路中消失。如果客戶端直接關閉連線,然後馬上建立下一次連線,那麼有可能新老連線使用的是同一個埠,舊連線因網路原因滯留在網路中的某些資料就會在新連線建立後到達服務端,這樣新老連線的資料教會發生混淆 3. msl表示報文最大生存時間,2msl表示傳送接收一個來回報文的最大生存時間 #### TCP協議如何來保證資料的順序性 ##### 流量控制 - 控制傳送方的傳送速度,讓接收方來得及接收而不至於資料丟失。 - 使用滑動視窗機制,a向b發資料,建立連線時b告訴a我的接收視窗rwnd=n,因此傳送視窗的位元組量不能大於該視窗。當報文某一欄位丟失b會向a傳送一個ack報文,Ack=1,ack=上次接收到的序列號隊尾+1,新的rwnd;當接收視窗滿了也會發送ack報文,當資料全部接受會發送一個ack,rwnd=0 ##### 擁塞控制 傳送方維持一個擁塞視窗cwnd,該視窗的大小隨網路擁塞程度動態變化 1. 慢開始演算法:建立連線時將cwnd設定為最大報文段mss的數值,試探性發送,收到確認資訊後逐倍加大cwnd的大小。cwnd有一個門限值,當cwnd < 門限則使用慢開始演算法,大於使用擁塞避免,等於則兩者即可。 2. 擁塞避免:與慢開演算法相比,cwnd不再是逐倍數放大,而是每次加1,讓其線性緩慢增長 3. 快重傳:要求接收方收到一個失序報文後立即發出確認報文而不是等到需要自己傳送資料時在攜帶該資訊。當收到連續3個重複的確認資訊時傳送方立即重傳該缺失報文 4. 快恢復:當傳送方連續收到三個重複確認資訊後,將慢開始門限減半,然後不執行慢開始而是使用擁塞避免演算法使cwnd視窗線性增大 #### TCP協議怎麼保證資料的可靠傳輸 ##### 校驗與重傳策略 - 校驗策略是說每一個tcp資料都會帶著資料的校驗和,服務端接收到tcp資料首先會驗證校驗和,如果驗證不對,服務端將丟棄這個tcp資料和不確認收到此報文段(希望傳送方重發該資料)。 - 重傳策略是說,每一次資料傳送是客戶端都會同時起一個定時器,如果在指定時間內沒有接收到服務端的確認,就把資料再發一次。定時器時長是一個動態變化的過程,簡單來說是由當前網路的擁塞程度和之前定時器時長的加權平均值確立的,但對於使用快恢復演算法之後的定時器則只跟當前網路擁塞程度有關。 #### TCP粘包,TCP拆包 ##### TCP粘包和TCP拆包是什麼 通過前面的學習我們知道,TCP協議是面向位元組流需要通過Socket獲取(/上傳)資料。Socket大門不可能是無限大的,它存在一個最大長度。報文大小與Socket大小有下面情況 ![tcp粘包](https://user-gold-cdn.xitu.io/2020/4/25/171af95316ef23a6?w=550&h=476&f=png&s=7395) 1. 如上圖中的第一根**bar**所示,服務端一共讀到兩個資料包,每個資料包都是完成的,並沒有發生粘包的問題, 2. 服務端僅收到一個數據包,這個資料包包含客戶端發出的兩條訊息的完整資訊,這個時候基於第一種情況的邏輯實現的服務端就蒙了,因為服務端並不能很好的處理這個資料包,甚至不能處理,這種情況其實就是TCP的粘包問題。 3. 服務端收到了兩個資料包,第一個資料包只包含了第一條訊息的一部分,第一條訊息的後半部分和第二條訊息都在第二個資料包中,或者是第一個資料包包含了第一條訊息的完整資訊和第二條訊息的一部分資訊,第二個資料包包含了第二條訊息的剩下部分,這種情況其實是傳送了TCP拆包問題,因為發生了一條訊息被拆分在兩個包裡面傳送了,同樣上面的伺服器邏輯對於這種情況是不好處理的。 ##### 什麼情況下會發生TCP粘包 1. TCP連線複用造成的粘包問題 2. TCP預設使用Nagle演算法,該演算法會導致TCP粘包 3. 資料包過大造成的粘包問題 4. 網路擁塞造成的TCP粘包 5. 接收方不及時接受快取區的包,造成一次接受多個包 **如何處理粘包、拆包** 通常會有以下一些常用的方法: 1. 使用帶訊息頭的協議、訊息頭儲存訊息開始標識及訊息長度資訊,服務端獲取訊息頭的時候解析出訊息長度,然後向後讀取該長度的內容。 2. 設定定長訊息,服務端每次讀取既定長度的內容作為一條完整訊息,當訊息不夠長時,空位補上固定字元。 3. 設定訊息邊界,服務端從網路流中按訊息編輯分離出訊息內容,一般使用‘\n’。 4. 更為複雜的協議,例如樓主最近接觸比較多的車聯網協議808,809協議。 ## 網路層 ### 沒錯,又是一個例子 某天,慕恩心血來潮準備給夏爾來個“飛鴿傳書”,於是她情意滿滿地寫了封信愉快的投遞到郵筒A(女孩子應該挺喜歡弄點小浪漫的吧)。然後負責A-B區域的郵遞員叔叔將郵件從A運輸到B,然後再經過一些傳遞最終到達夏爾手中。 ![網路層.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952ef81c78d?w=1147&h=689&f=png&s=54999) 上述例子中我們著重關心一下郵筒,分解一下它的工作步驟。 1. 接收郵件(源地址) 2. 查詢最近郵筒地址(因為如果超遠距離傳輸,不可能讓一個郵遞員叔叔橫跨幾千裡就為了給你倆飛鴿傳書吧) 3. 轉發郵件到最近的郵筒(或目標地址)。 聰明的你也想到了,這就是網路層所起到的作用。不過路由器替代了上述郵筒的功能,而路由器是怎麼分組轉發資料,以及路由器是怎麼尋找下一個路由器的呢?請聽我一一道來。 ### 虛電路和分組交換 首先需要明確的是,網路層其實也分為面向連線和無連線的,被稱為虛電路網路和資料報網路。與你想的一樣面向連線那麼需要事先建立連線管道,更多資訊可以檢視《計算機網路 自頂向下》。其適用於ATM機等,而因特網使用的是資料報網路,這也是我們學習的重點,所以之後主要談的是該網路。 ### 路由器工作原理 ![router.png](https://user-gold-cdn.xitu.io/2020/4/25/171af952effb7e6f?w=832&h=401&f=png&s=171867) ​ 路由器由輸入埠,交換結構,輸出埠,和路由選擇處理器四個部分組成(注意這裡的埠不同於傳輸層的埠,類似於物理上的介面)。 1. 輸入埠: 它將一條輸入的物理鏈路與路由器的物理層相連線,同時它能實現入鏈路遠端的資料鏈路層和路由器資料鏈路層的互動,更為重要的是它會根據最長公共字首匹配原則查詢輸出埠。 2. 交換結構:將輸入埠和輸出埠相連線。 3. 輸出埠:輸出埠從交換結構中接收分組,並將通過資料鏈路層和物理層傳輸這些分組。 4. 路由選擇處理器:執行路由選擇協議,維護路由選擇表和連線的鏈路狀態資訊併為路由器計算轉發表。 ### IPv4 ![ipv4.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95306cd9512?w=565&h=408&f=png&s=230635) 之前提到了很多關於ip地址,ip協議的點,但提到路由器原理時貌似沒有跟ip沒什麼關係,是這樣的嗎?其實從上圖資料報不難看出源地址和目的地址跟路由器的輸入埠,輸出埠有著千絲萬縷的關係。那麼首先我們還是來看看報文各欄位的含義吧。 1. 版本: 規定了資料包的IP協議版本,現在使用的有ipv4和ipv6兩種協議。 2. 首部長度: 分隔首部和資料欄位,但大多數IP資料報具有20位元組首部通常不包含該欄位 3. 服務型別: 這是一個高階選項,由路由器管理員控制,可以為特定使用者(VIP)提供特定等級的服務。 4. 資料報長度: IP資料報的總長度 5. 標識、標值、片偏移: 這三個欄位與IP分片有關,用於保證IP分片後組裝的順序性和丟包等差錯檢測。 6. 壽命(TTL,相信Ping過ip地址的同學都對這個欄位有所瞭解): 用於確保資料報不會永遠在網路中迴圈(為什麼資料報會在網路中迴圈呢?)。每當資料報由一臺路由器處理時,該欄位減1,若TTL欄位減為0,則該資料報必須丟棄。 7. 首部校驗和: 與之間類似,用於檢測位元錯誤 8. 源和目的IP地址: 每臺主機和路由器都有一個IP地址(不一定時公網IP),當某源生成一個數據報時,它在源IP欄位中插入它的IP地址,在目的IP地址欄位中插入其最終目的地的地址。 9. 選項: 選項欄位允許IP首部被擴充套件。 10. 資料: payload,需要傳輸的資料 #### 點分十進位制 從IPv4的資料報文中,我們得知ip地址是由32為位元標識,理論上可以由40億公網ip地址(去年已全部分配完畢)。但32位元位表示特別不方便,於是通常我們都是用`十進位制 . 十進位制`進行標識,稱為點分十進位制。如223.0.0.1(每8個位元位用十進位制標識,然後用`.`分隔)。 #### 子網掩碼 ip地址是由權威機構分發的,但是不可能讓一個結構給全世界每個人發一個ip地址。更合理的做法是採用之前應用過的分散式的思想,某機構向權威機構申請一部分ip地址 => 該機構向其內部人員發放ip地址。這樣怎麼進行劃分就成了一個問題,你總不可能隨機分配吧(不利於管理),所以這裡就有了子網掩碼的概念。`223.0.0.0/24` 中`/24`就是子網掩碼,它表示該子網前24個位元位不變,後8位可以由該子網自由分配。也就是說該機構拿到了這塊地址後,就可以向內部人員分配`223.0.0.1`,`223.0.0.2`,`223.0.0.99`...這樣網際網路就被劃分為了許許多多的子網路,值得注意的時子網掩碼最多30位(規定子網最少容納兩臺主機)。 #### ip地址不夠用咋辦 但劃分子網始終需要是2的倍數同時總共也就40億個,對於資訊大爆炸的今天完全不夠用,那麼怎麼解決呢?這個問題專家們早就想到了,所以很早開始了ipv6的協議制定,當然替換一個協議相當於動搖了一個摩天大廈的根基,這務必是一個緩慢的過程。所以聰明的開發人員採用了**網路地址轉換**(NAT)的方法擴充了ip地址 #### NAT 提到這個詞大家估計還有點疑惑這是個啥,不過提到內網穿透,大家估計就來勁了。還是用圖說一下原理吧。 ![NAT.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9533f181291?w=1147&h=624&f=png&s=60277) 上圖簡單地反映了內網穿透的原理(其實就是利用了傳輸層埠的多路複用)。我們知道HTTP協議的預設埠是80埠,同時使用者只能訪問公網ip上的資訊。所以當右邊的使用者想要訪問左邊使用者上的服務時,會在公網伺服器上開放一個埠然後與區域網的埠連線(實際上是80埠監聽時,將該請求轉發到某埠),之後建立了一條通訊隧道,與之類似,左邊使用者也與公網伺服器建立一條隧道。這樣看起來兩個使用者通過公網伺服器(中介)進行相互訪問一樣。舉個生活中的例子就是,在同一個家庭組(WIFI網路下),三大運營商只會隨機分配給你一個ip,但連線該WIFI的通常不少於一人,那麼虛擬子網路中的使用者使用虛擬ip與其他家庭組使用者之間進行通訊時所用到的技術就涵蓋了內網穿透。 #### ICMP ICMP協議是一個用於差錯報告的協議,它的報文型別如下 ![icmp.png](https://user-gold-cdn.xitu.io/2020/4/25/171af95355c86a63?w=604&h=463&f=png&s=175627) ### ipv6 ![ipv6.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953629b5571?w=483&h=265&f=png&s=95603) 從資料報就可以看出ipv6相比ipv4更加簡潔清晰,刪去了很多不必要的欄位。然後將ip地址的位元位數從32位增加到128位,據說地球上的每一粒沙都可以分配一個ip地址。以下為欄位說明: 1. 版本: 與ipv4起到的作用一樣。 2. 流量型別: 標識流量的優先順序。 3. 流標籤: 用於標識一條資料報的流,可以按傳送方的要求進行特殊處理的流,可以設定優先順序(會員機制)。更多內容請參考《計算機網路 自頂向下方法》 4. 有效載荷長度: Content資料的長度 5. 下一個首部: 該欄位標識資料報中內容需要交給哪一個協議(如TCP或UDP) 6. 跳限制: 資料報每經過路由轉發其值-1,當其值為0時,該資料報被丟棄。與ipv4中TTL類似 #### IPv4如何向IPv6遷移 我們注意到兩個協議上都有版本欄位,那麼是否可以通過修改該欄位進行遷移呢?當然是不行的,ipv4和ipv6資料報首部完全不一樣,沒辦法採用與原協議方法進行傳輸。 所以比較直接的方法是採用雙棧的方法,假定兩個IPv6節點要是有IPv6資料報進行互動,但他們是由中間IPv4路由器互聯的。我們將兩臺IPv6路由器之間的中間IPv4路由器的集合稱為一個隧道。隧道中,IPv6將其所有欄位放到IPv4的資料報欄位中,再由IPv4傳輸給另一個IPv6,詳情參考《計算機網路 自頂向下方法》 ### RIP,OSRF 之前有提到過路由選擇演算法,而實現路由選擇有兩個比較有名的協議分別是RIP和OSPF。 #### RIP RIP是一種距離向量協議,每個路由器內部維護了一個路由選擇表的RIP表,它包含了當前路由到達目標地所經歷的跳數。 ![rip1.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953848aadbb?w=743&h=230&f=png&s=108755) ![rip2.png](https://user-gold-cdn.xitu.io/2020/4/25/171af9538c6a001f?w=463&h=217&f=png&s=45363) #### OSPF OSPF是基於鏈路狀態的協議,路由器在本地執行迪傑斯特拉演算法(最短路徑演算法),求出當前路由器據個節點的權重,然後將所有鏈路費用設定為1,然後如何根據權重選擇鏈路由管理員自己決定。 #### RIP和OSPF的區別 ##### 1、路由演算法: RIP協議是一種典型的距離向量協議,它使用的也是距離向量演算法,該演算法可以用一句話來概括:**進行路由更新時傳遞路由表。** OSPF協議則是一種典型的鏈路狀態協議,它使用的是Dijkstra演算法,該演算法是**通過OSPF鄰居之間泛洪傳送LSA(鏈路狀態通告)來進行路由更新**,並且它會計算出去往所有已知目的地址的所有無環路徑,以不同種類的LSA型別將其儲存到LSDB(鏈路狀態資料庫)中,所有執行OSPF的裝置都會有自己的LSDB,然後將LSDB中最優的LSA更新到路由表中。 ##### 2、度量值: RIP協議的度量值是以**跳數**來計算的,即每經過一跳,度量值就會加一,這樣的度量值計算並不符合當前的網路環境,因為當前頻寬爆炸性的增長,可能會導致RIP選擇了次優路徑。 OSPF協議的度量值計算則是以**頻寬**為基準來計算的,其公式為10的8次方/頻寬,所以從度量值的計算方式來看,OSPF要更加合理。 ##### 3、最大網路直徑: RIP的最大網路直徑為**15**,也就是說RIP協議所能傳遞路由資訊的最大跳數就是15跳,超過15跳就表示不可達。 OSPF協議的最大網路直徑為**255**,可以適應更大的網路環境。 ##### 4、鄰居關係的建立: RIP**本身並沒有鄰居關係**的概念,它只會將資訊傳送給所有直連的且執行RIP協議的所有裝置。 OSPF則**有很詳盡的鄰居**概念,並且根據互動LSA的不同,可以分為鄰居(2-way)以及鄰接(full)兩種不同的鄰居關係,前者只會相互發送hello報文,維持鄰居關係,而後者則會相互發送路由更新。 ##### 5、防環機制: RIP協議作為典型的距離向量協議,它的防環機制有兩種:**水平分割和毒性逆轉**,簡單來說,水平分割就是從一個介面接收的路由更新,不會再從該埠傳送出去。毒性逆轉則是從一個介面接收的路由更新,會再從該介面發出去,但是會將其置為不可達狀態(16跳)。 OSPF協議**從演算法上就可以達成防環**,請參考第一條... ##### 6、路由傳遞機制: RIP協議預設**會進行自動彙總**(有類路由協議),即傳輸的路由條目會自動進行主類的彙總,這樣會導致路由條目不精確,後續RIP協議為了解決該問題,將RIPV1升級為RIPV2,V2版本不僅支援手動彙總,使路由條目傳遞更加精準,而且將路由更新方式從V1的廣播變成了V2的組(224.0.0.9),提升了路由更新效率。 OSPF協議預設**不會進行自動彙總**(無類路由協議),並且會在每個網段的鄰居中選舉一個DR指定路由器,所有路由更新會通過224.0.0.6傳送給DR,DR再通過224.0.0.5傳送給其他所有鄰居,這樣可以防止重複的路由條目更新。 這個點是mark[“RIP協議”與“OSPF協議”的相同點與不同點是什麼?](https://www.jianshu.com/p/2898dc090e1d)的,為了方便整理到了一起,大家可以去看看原文。 ## 資料鏈路層 ### 如你所想,例子如期而至 夏爾去外地參加比賽了,慕恩打算在他生日那天給他一個驚喜(閃現貼臉)。她可以選擇飛機,火車和自行車作為交通工具但最終出發點和目的地都是一致的。 ![travel.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953ae721119?w=646&h=482&f=png&s=88475) 鏈路層的不同鏈路就像連線兩地的路線,鏈路層的作用就是將A地的資料通過鏈路傳輸到B地。 ### 鏈路層的特點 1. 封裝成幀: 將網路層的資料報封裝為多個數據幀(由一個數據欄位和若干首部欄位組成)。 2. 鏈路接入: MAC協議規定了幀在鏈路上的傳輸規則。 3. 可靠互動: 類似於傳輸層的TCP,鏈路層也能提供可靠的互動。但對於一些低位元差錯的鏈路,如光纖、同軸電纜等,可靠互動被認為時不必要的開銷。 4. 差錯檢測和糾正: 傳送方在幀中加入校驗位位元,接收方對資料幀進行差錯檢測和糾正。 ### 差錯檢查和糾正位元 鏈路層的差錯檢查和糾正有奇偶校驗法,校驗和法,CRC編碼法。 #### 奇偶校驗法 奇偶校驗法的思路很簡單,就是在資料幀中增加一個位元位使資料幀為奇數稱為奇校驗,為偶數稱為偶校驗。接收方接收到資料後只需檢測資料幀為奇數還是偶數。但顯然這樣簡單的做法會帶來一些問題,雖然同一資料幀多個位元位都被噪聲干擾產生位元變化的概率很低,但這樣的情況一旦發生了,該差錯檢驗方法就沒有起到作用。同時奇偶校驗法只能檢測差錯而不能糾正錯誤。 #### 校驗和法 與之前傳輸層差錯檢驗的方法基本一致。 #### 迴圈冗雜檢測(CRC)編碼 1. 傳送方和接收方協商一個r+1位元模式,稱為生成多項式,我們將其表示為G 2. 對於一個給定的資料段D,傳送方要選擇r個附加位元R,並將它們附加到D上,使之得到的d+r模式用模2運算恰好能被G整除。 3. 接收方用G去除接收到的d+r位元,如果餘數為零則無差錯,否則則認為資料出錯丟棄該幀。 ​ ![CRC.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953b8ad5c1e?w=540&h=179&f=png&s=57222) ### 多路訪問鏈路和協議 #### 點到點傳播和廣播 我們將鏈路連線的裝置(交換機,路由器,主機等)稱為節點。 點對點鏈路由鏈路一端的單個傳送方和鏈路另一端的單個接收方組成。 廣播鏈路能讓多個傳送和接收節點都連線到相同的單一的、共享的廣播通道上。(這裡的廣播跟教室裡老師上課的情景很像) #### 通道劃分協議 ##### 時分複用 1. 將時間分割為一個或多個時間幀(與前面提到的資料幀不一樣),並進一步劃分每個時間幀為N個時隙。 2. 為每條鏈路分配一個時隙 3. 每條鏈路在分配到的時隙內進行資料傳輸 ![shifen.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953f5f81cfa?w=476&h=144&f=png&s=43262) ##### 頻分複用 與時分複用類似,所謂頻分複用是把頻寬劃分為多個通道分配給每條鏈路,資料在分配好的頻率下進行傳輸。 ##### 碼分複用 碼分複用對每個節點分配一種不同的編碼,然後每個節點用它唯一的編碼來對它傳送的資料進行編碼。 #### 隨機接入協議 ##### 時隙(ALOHA) 1. 當節點有一個新幀要傳送時,它等到下一個時隙開始並在該時隙傳輸整個幀。 2. 如果沒有碰撞,該節點成功的傳輸它的幀 3. 如果有碰撞,則該節點在時隙結束之前檢測到這次碰撞,該節點有隨機概率p的機率重傳該幀。 ##### 具有碰撞檢測的載波偵聽多路訪問(CSMA/CD) 1. 介面卡從網路層獲取資料報,封裝成幀後放入設配器快取。 2. 如果介面卡偵聽到通道空閒,它開始傳輸幀。在另一方面,如果介面卡監聽到通道正在忙,它將等待,直到監聽到通道空閒時再開始傳輸幀。 3. 在傳輸過程中,介面卡監視來自其他使用該廣播通道的介面卡的訊號能量的存在。 4. 如果介面卡傳輸整個幀而未檢測到來自其他介面卡的訊號能量,該介面卡就能完成該幀。在另一方面,如果介面卡在傳輸時檢測到來自其他介面卡的訊號能量,它中止傳輸。 5. 中止傳輸後,介面卡等待一個隨機時間量,然後返回步驟2。 #### 輪流協議 ##### 輪詢協議 輪詢類似於一箇中介模式,主節點能夠檢測通道上是否缺乏訊號。主節點輪詢各個節點,告訴每個節點能夠傳輸幀的最多數量。 ##### 令牌傳遞協議 當一個節點擁有令牌且有資料幀需要傳輸時,它傳送最大數目的幀數,然後將令牌轉發給下一個節點。 如果擁有節點的令牌沒有資料幀需要傳輸,那麼它會立即將令牌轉發給下一個節點。 ### 鏈路層定址 #### MAC地址 又稱LAN地址,實體地址,嚴格來說是網絡卡的地址而不是主機的地址。由48個位元位構成,前24位位標誌位,後24位為地址為,採用十六進位制表示。 #### 地址解析協議(ARP) 接收一個IP地址,返回一個MAC地址(先從快取找,沒有的話再廣播),RARP與之功能相反即接收一個MAC地址返回一個IP地址。 #### 乙太網 “乙太網幾乎佔據了現有的有限區域網市場,它之於區域網的地位不亞於因特網之於全球聯網的地位。” ##### 乙太網的結構 ![LAN.png](https://user-gold-cdn.xitu.io/2020/4/25/171af953f5f3c166?w=668&h=55&f=png&s=32255) 1. 資料欄位: 該欄位承載了P資料報。 2. 目的地址: 包含了目的介面卡的MAC地址。 3. 源地址: 包含了傳輸該幀到區域網上的介面卡的MAC地址。 4. 型別欄位: 允許乙太網複用多種網路層協議。 5. CRC欄位: 判定接收介面卡檢測幀中是否引入了差錯。 6. 前同步碼: 該前同步碼的前7個位元組的值都是10101010,最後一個位元組時10101011。前同步碼欄位的前7個位元組用於喚醒接收介面卡,並且將他們的時鐘和傳送方的時鐘同步。 #### 鏈路層交換機 ##### 交換機的特點 1. 自主學習,即插即用。交換機維護了一個交換機表(類似於路由表,只是使用的是MAC地址),初始化時,它會向與之相連的節點進行廣播以獲取它們的MAC地址,然後當一個節點很久沒有接入到鏈路中時,則從交換機表中刪除該MAC地址。 2. 交換擁有過濾和轉發的功能,過濾是決定一個幀應該轉發到某個介面還是應當將其丟棄的交換機功能;轉發是決定一個幀應該被導向哪個介面。 3. 在使用交換機構建的區域網中,不會因為碰撞而浪費頻寬,並且不同鏈路能夠以不同的速率執行在不同的媒體上,因此,對於原有的裝置與新裝置混用,交換機是理想的。 ##### 交換機和路由器比較 1. 交換機是第二層的分組交換機,而路由器是第三層的分組交換機。 2. 交換機即插即用 3. 大型交換網路中要求主機和路由器中由大量的ARP表,這將生成可觀的ARP流量和處理量。 ## 物理層 傳輸最底層的訊號如電訊號,光訊號等(高低電平分別表示1和0)。 [更多資訊](https://juejin.im/post/5d28508f51882569755f4d64) ## 網路安全 ### 網路攻擊 #### XSS攻擊 - 攻擊方式 跨站指令碼攻擊是指惡意攻擊者往Web頁面裡插入惡意Script程式碼,當用戶瀏覽該頁之時,嵌入其中Web裡面的Script程式碼會被執行,從而達到惡意攻擊使用者的目的。 - 解決方案 為cookie設定httpOnly屬性,對使用者的輸入進行檢查,進行特殊字元過濾 #### CSRF攻擊 - 攻擊方式 CSRF跨站點請求偽造(Cross—Site Request Forgery),跟XSS攻擊一樣,存在巨大的危害性,你可以這樣來理解: 攻擊者盜用了你的身份,以你的名義傳送惡意請求,對伺服器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義傳送郵件、發訊息,盜取你的賬號,新增系統管理員,甚至於購買商品、虛擬貨幣轉賬等。 - 解決方案 使用驗證碼,檢查https頭部的refer,使用token #### 中間人攻擊 - 攻擊方式 也稱瀏覽器劫持,web劫持。簡單來說就是黑客通過各種各樣的技術手段,在服務端傳送出的HTTP報文與顯示屏呈現的WEB頁面之間做了一些手腳,纂改網頁的部分或全部內容。主要分為網路挾持纂改和終端挾持纂改(比如盜版遊戲中植入的一些木馬經常會纂改你的瀏覽器主頁)。 [更多資訊](https://www.zhuyingda.com/blog/article.html?id=7&origin=gold) - 解決方案 使用HTTPS協議傳輸報文,遠離不安全的網站。 ### 網路安全是什麼 1. 報文的機密性:只有傳送發和希望的接收方能夠理解傳輸報文的內容 2. 報文完整性:報文在傳輸的過程中未發生變化或者惡意篡改 3. 執行安全性:幾乎所有的機構都有與公共因特網相連線的區域網,這些網路都因此潛在地能夠被危及安全 ### 密碼學 #### 對稱加密 ##### 對稱加密演算法 傳送方和接收方持有同一把金鑰,傳送訊息和接收訊息都使用該金鑰。相比非對稱加密演算法,該演算法加密和解密的速度都更快,但由於雙方都需要事先直到金鑰,因此在傳輸過程中更容易被捕獲,安全性不如非對稱。 ##### 愷撒密碼 大名鼎鼎的**尤利烏斯·愷撒**是古羅馬共和國著名的執政官,他的傳奇事蹟無需概述。我們都知道行軍打仗除了兵馬糧草之外,情報也是非常重要的,現代戰爭儼然一副情報戰。於是愷撒使用了一種加密方法進行情報加密再讓接收方對情報進行解密,我想這也是他能在高盧戰場取得重大勝利的原因之一吧。 ``` //愷撒密碼,在闡述網路分層的例子我們就用到了這種加密方法 a b c d e f g h i j k l m n o p q r s t u v w x y z (26個字母的閉環) k = 5 i love u n qtaj z ``` ##### 塊密碼 1. 將資料報文分塊 2. 每一塊報文由一個T表進行加密處理 3. 將塊報文組裝起來 ![blockS.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af953f7e2eaa2?w=860&h=516&f=jpeg&s=94498) ##### 流密碼 1. 在加密報文之前,傳送方生成一個隨機位元串k,作為初試向量`c0`,傳送給接收方。 2. 傳送方將初始資料`m1`與隨機向量`c0`亦或後使用金鑰進行加密 3. 對於第`i`個數據報,傳送方根據`ci = Ks(mi ^ c(i-1))`生成第i個密文塊 4. 接收方根據`Ks`進行解密 上述過程中隨機生成的位元串是為了標識資料報。因為有一定可能出現相同的資料報,如果不加入隨機識別符號,那麼相同的資料報會採用相同的加密方法,攻擊者可能潛在地猜出明文。 #### 非對稱加密 ##### 非對稱加密演算法 接收方生成一個公鑰和一個私鑰,將公鑰傳送給傳送方。傳送方通過該公鑰對會話進行加密然後傳送到接收方,接收方通過私鑰進行解密。傳送過程中就算被竊取資料,沒有服務端的私鑰也難以對資訊進行解密,因而安全性較高。 ##### RSA演算法 最常用的非對稱加密演算法之一 1. 選擇兩個大素數`p`和`q`,這兩個值越大,就越難以破解,而執行加密和解密所用的時間也就越長。 2. 計算 `n = pq`和` z = (p-1)(q-1)` 3. 選擇小於n的一個數`e`,且使得`e`和`z`沒有(非1的)公因數。(也就是e和z互素) 4. 求一個數`d`,使得 `ed-1` 可以被`z`整除。`ed mod z = 1`(mod 是取餘的意思) 5. 接收方使用的外界可用的公鑰Key+是一對數`(n,e)`,其私鑰Key-是一對數`(n,d)` - 傳送方傳送給接收方一個由`m`表示的位元組合資料,且`m m ^ (ed) mod n` 3. 數論中有這樣一個結論:如果`p`和`q`是素數,且有`n = pq,z = (p-1)(q-1)`則`x ^ y mod n <=> x ^ (y mod z) mod n `,應用這個結論,對於`x = m,y = ed, m < n`,可得`m ^ ed mod n = m ^ 1 mod = m` [RSA演算法原理(一)](http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html) [RSA演算法原理(二)](http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html) #### 報文完整性 ##### 密碼雜湊函式 校驗和算是比較簡單的密碼雜湊函式,因此所謂的密碼雜湊函式以`m`作為輸入,並計算得到一個稱為雜湊的固定長度的字串`H(m)`,要求對於任意兩個不同的報文`x,y`使得`H(x) != H(y)` 常見的密碼雜湊函式有[MD5加密演算法](https://www.cnblogs.com/hjgods/p/3998570.html) ##### 報文鑑別碼 1. 傳送方生成報文`m`,用`s`級聯`m`以生成`m + s`,並計算雜湊`H(m + s)`。`H(m + s)`被稱為報文鑑別碼 2. 傳送方將報文鑑別碼附加到報文`m`上,生成擴充套件報文`(m,H(m + s))`,並將該擴充套件報文傳送給接收方 3. 接收方收到一個擴充套件報文`(m,h)`,由於知道`s`,計算出報文鑑別碼`H(m + s)`。如果`H(m + s) = h`,那麼接收方表示報文沒問題。 ##### 數字簽名 1. 傳送方用將初始報文通過雜湊函式生成擴充套件報文,然後再用自己的私鑰進行數字簽名,然後傳送給接收方 2. 接收方使用公鑰解密得到雜湊函式,再與維護在本地的雜湊函式表中的雜湊函式進行比對,如果匹配,則接收方可以確認報文的完整性以及傳送方的可信任性 ##### 公鑰認證 1. 服務方向CA證書頒發機構申請證書認證 2. 客戶方向服務方請求服務,服務方將證書發給客戶方 3. 客戶方使用本地內建的證書公鑰與服務方傳送的證書中的公鑰進行校對 4. 驗證通過後,再商量建立金鑰建立的協議版本,加密方式等,詳情見SSL。 ### 應用場景 #### 應用層 ##### token使用者認證 - 組成 1. uid(使用者唯一標識) 2. time(當前時間的時間戳) 3. sign(簽名,token前幾位以雜湊演算法壓縮成的一定長度十六進位制字串) - 特點 1. 服務端無狀態化、支援在多個服務間共享 2. 安全,可以防止csrf攻擊 3. 完全由應用管理,可以避開同源策略 - 流程 1. 登入 ![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d33b4cd?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 2. 業務請求 ![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d5aa746?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 3. token過期,重新整理token ![image](https://user-gold-cdn.xitu.io/2018/1/27/161375750d060f97?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) #### SSL -讓TCP更加安全 SSL被稱為安全套接字層,SSL版本3的一個稍加修改的版本被稱為運輸層安全性(TLS)。 之前談到HTTPS協議的安全性時提到了SSL,這裡複述一下吧: ##### ssl握手過程 1. 客戶端向服務端發出加密通訊的請求。這被叫做clientHello請求, - 包括支援的協議版本,一個隨機數用於等會生成會話金鑰,支援的加密方法,支援的壓縮方法 2. 迴應,serverhello, - 確認加密通訊協議的版本,一個隨機數用於稍後生成會話金鑰,確定加密方法,伺服器的證書 3. 客戶端驗證服務端證書是否為可信機構頒步,如果不可信會給訪問者一個警告有起決定是否繼續通訊, - 返回一個隨機數用於公鑰加密,編碼改變通知(之後的資訊都用雙方商定的加密方法和金鑰發生),客戶端握手結束的通知 4. 服務端收到客戶端的第三個隨機數後,計算生成本次會話用的“會話金鑰”,然後向客戶端傳送下面資訊: - 編碼改變通知,表示隨後的資訊都將用雙方商定的加密方法和金鑰傳送。伺服器握手結束通知,表示伺服器的握手階段已經結束。這一項同時也是前面傳送的所有內容的hash值,用來供客戶端校驗。 [更多資訊](https://imququ.com/post/optimize-tls-handshake.html) #### 網路層 ##### IPsec IPsec有兩種不同的分組形式,一種是隧道模式,一種是運輸模式。更為蛇和VPN的隧道模式比運輸模式部署得更為廣泛。 ![IPsec.jpg](https://user-gold-cdn.xitu.io/2020/4/25/171af9542448b7a9?w=893&h=330&f=jpeg&s=54648) 1. 在初始IPv4資料報後面附上一個“ESP尾部”欄位 2. 使用演算法和由SA規定的金鑰加密該結果 3. 在這個加密量的前面附加上一個稱為“ESP首部”的欄位 4. 使用演算法和由SA規定的金鑰生成一個覆蓋整個enchilada的報文鑑別碼 5. 該報文鑑別碼附加到enchilada的後面形成載荷 6. 生成一個具有經典IPv4首部欄位的全新IP首部,該新首部附加到載荷之前 [更多資訊](https://blog.csdn.net/NEUChords/article/details/92968314?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1) #### 防火牆的工作是什麼 lin