計算機網絡常用知識總結!

OSI 七層模型

「物理層」

首先解決兩臺物理機之間的通信需求,具體就是機器 A 往機器 B 發送比特流,機器 B 能收到比特流。

物理層主要定義了物理設備的標準,如網線的類型,光纖的接口類型,各種傳輸介質的傳輸速率。

主要作用是傳輸比特流(0101二進制數據),將比特流轉化爲電流強弱傳輸,到達目的後再轉化爲比特流,即常說的數模轉化和模數轉換。

這層數據叫做比特。「網卡工作在這層」

物理層是 OSI 七層模型的物理基礎,沒有它就談不上數據傳輸了

物理層就是由實物所承載的,所以作比喻的話,公路、汽車和飛機等承載貨物(數據)的交通工具,就是物理層的象徵

「數據鏈路層」

在傳輸比特流的過程中,會產生錯傳、數據傳輸不完整的可能。

數據鏈路層定義了**「如何格式化數據進行傳輸」**,以及如何控制對物理介質的訪問。通常提供錯誤檢測和糾正,以確保數據傳輸的準確性。

本層將比特數據組成幀,交換機工作在這層,對幀解碼,並根據幀中包含的信息把數據發送到正確的接收方。

該層負責物理層面上互連的節點之間的通信傳輸。例如與 1 個以太網相連的兩個節點間的通訊。

常見的協議有 HDLC、PPP、SLIP

數據鏈路層會將0、1序列劃分爲具有意義的數據幀傳送給對端(「數據幀的生成與接收」

「網絡層」

隨着網絡節點的不斷增加,點對點通訊需要通過多個節點,如何找到目標節點,如何選擇最佳路徑成爲首要需求。

網絡層主要功能是將網絡地址轉化爲對應的物理地址,並決定如何將數據從發送方路由到接收方。

網絡層通過綜合考慮發送優先權、網絡擁塞程度、服務質量以及可選路由的花費來決定從一個網絡中節點 A 到另一個網絡中節點 B 的最佳路徑。

由於網絡層處理並智能指導數據傳送,路由器連接網絡隔斷,所以路由器屬於網絡層。

此層的數據稱之爲數據包。本層需要關注的協議TCP/IP協議中的 IP 協議。

網絡層負責將數據傳輸到目標地址。目標地址可以使多個網絡通過路由器連接而成的某一個地址。因此這一層主要負責**「尋址和路由選擇」**。主要由 IP、ICMP 兩個協議組成

網絡層將數據從發送端的主機發送到接收端的主機,兩臺主機間可能會存在很多數據鏈路,但網絡層就是負責找出一條相對順暢的通路將數據傳遞過去。傳輸的地址使用的是 IP 地址。IP 地址通過不斷轉發到更近的 IP 地址,最終可以到達目標地址

「傳輸層」

隨着網絡通信需求的進一步擴大,通信過程中需要發送大量的數據,如海量文件傳輸,可能需要很長時間,網絡在通信的過程中會中斷很多次,此時爲了保證傳輸大量文件時的準確性,需要對發送出去的數據進行切分,切割爲一個一個的段落(Segement)發送,其中一個段落丟失是否重傳,段落是否按順序到達,是傳輸層需要考慮的問題。

傳輸層解決了主機間的數據傳輸,數據間的傳輸可以是不同網絡,並且傳輸層解決了**「傳輸質量」**的問題。

傳輸層需要關注的協議有 TCP/IP 協議中的TCP協議和UDP協議。

「會話層」

自動收發包,自動尋址。

會話層作用是**「負責建立和斷開通信連接」**,何時建立,斷開連接以及保持多久的連接。常見的協議有 ADSP、RPC

「表示層」

Linux 給 WIndows 發包,不同系統語法不一致,如 exe 不能在Linux下執行,shell 不能在 Windows 不能直接運行。於是需要表示層。

解決**「不同系統之間通信語法問題」**,在表示層數據將按照網絡能理解的方案進行格式化,格式化因所使用網絡的不同而不同。

它主要負責數據格式的轉換。具體來說,就是講設備固有的數據格式轉換爲網絡標準格式。常見的協議有ASCII、SSL/TLS

「應用層」

規定發送方和接收方必須使用一個固定長度的消息頭,消息頭必須使用某種固定的組成,消息頭中必須記錄消息體的長度等信息,方便接收方正確解析發送方發送的數據。

應用層旨在更**「方便應用從網絡中接收的數據」**,重點關注TCP/IP協議中的 HTTP 協議

四層傳輸層數據被稱作**「段」**(Segments);

三層網絡層數據被稱做**「包」**(Packages);

二層數據鏈路層時數據被稱爲**「幀」**(Frames);

一層物理層時數據被稱爲**「比特流」**(Bits)。

TCP 和 IP 模型

OSI 模型注重通信協議必要的功能;TCP/IP 更強調在計算機上實現協議應該開發哪種程序

「TCP/IP 劃分了四層網絡模型」

「四層網絡協議的作用」

「舉個例子:」

我們需要發送一個**「index.html」**。

兩臺電腦在應用層都使用 HTTP 協議(即都使用瀏覽器)。

在傳輸層,TCP 協議會將 HTTP 協議發送的數據看作一個數據包,並在這個數據包前面加上 TCP 包的一部分信息(部首)

在網絡層,IP 協議會將 TCP 協議要發送的數據看作一個數據包,同樣的在這個數據包前端加上 IP 協議的部首

在數據鏈路層,對應的協議也會在 IP 數據包前端加上以太網的部首。

源設備和目標設備通過網線連接,就可以通過物理層的二進制傳輸數據。

數據鏈路層,會使用對應的協議找到物理層的二進制數據,解碼得到以太網的部首信息和對應的 IP 數據包,再將 IP 數據包傳給上層的網絡層。

數據鏈路層 > 網絡層 > 傳輸層 > 應用層,一層層的解碼,最後就可以在瀏覽器中得到目標設備傳送過來的**「index.html」**。

「TCP/IP 協議族」

從字面意義上來講,TCP/IP 是指**「傳輸層」**的 TCP 協議和**「網絡層」**的 IP 協議。

實際上,TCP/IP 只是利用 IP 進行通信時所必須用到的協議羣的統稱。

具體來說,在網絡層是 IP/ICMP 協議、在傳輸層是 TCP/UDP 協議、在應用層是 SMTP、FTP、以及 HTTP 等。他們都屬於 TCP/IP 協議。

網絡設備

交換機

交換機可以接入多臺電腦

每個電腦網卡的 **「MAC 地址」**都是不一樣的,電腦發送數據時,數據頭部攜帶網卡的 MAC 地址,用 MAC 地址標識來不同的電腦

交換機就可以識別數據頭部的 MAC 地址來區分不同的電腦

交換機除了能識別不同的電腦,還需要找到電腦連接的**「交換機端口」**,才能順利的把數據從相應端口發送出去

交換機通過**「自學機制」**,把學習到的設備 MAC 地址和交換機端口號添加到 **「MAC 地址表」**,並根據 MAC 地址表進行數據**「轉發」**

路由器

交換機需要記錄的 MAC 地址表也越來越多,需要的交換機也越來越多

但是交換機的**「容量和性能有限」**,MAC 地址表無法記錄全世界電腦的 MAC 地址和對應的端口號,MAC 地址表太大也無法快速查找到對應的 MAC 地址表項

於是就有了三層網絡設備**「路由器」**,路由器可以把全世界的網絡連接起來

局域網內的網絡連接可以使用**「交換機」**,例如一個公司內的網絡或者一個校園內的網絡通過交換機連接

不同區域的局域網互聯使用**「路由器」**

那麼如何區分不同的網絡區域呢?又是如何跨網絡區域進行數據轉發的呢?

路由器有多個端口,分別連接不同的網絡區域,不同網絡區域的 IP 地址**「網絡號不同」**

它通過識別目的 IP 地址的**「網絡號」**,再根據**「路由表」**進行數據轉發

HTTP

「請求方法」

HTTP1.0 定義了三種請求方法:GET, POST 和 HEAD 方法。

HTTP1.1 新增了六種請求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

| 序 號 | 方法 | 描述 | | --- | --- | --- | | 1 | GET | 請求指定的頁面信息,並返回實體主體。 | | 2 | HEAD | 類似於 GET 請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 | | 3 | POST | 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST 請求可能會導致新的資源的建立和 / 或已有資源的修改。 | | 4 | PUT | 從客戶端向服務器傳送的數據取代指定的文檔的內容。 | | 5 | DELETE | 請求服務器刪除指定的頁面。 | | 6 | CONNECT | HTTP/1.1 協議中預留給能夠將連接改爲管道方式的代理服務器。 | | 7 | OPTIONS | 允許客戶端查看服務器的性能。 | | 8 | TRACE | 回顯服務器收到的請求,主要用於測試或診斷。 | | 9 | PATCH | 是對 PUT 方法的補充,用來對已知資源進行局部更新 。 |

「GET 請求和 POST 請求的區別」

  1. GET 請求的請求參數是添加到 head 中,可以在 url 中可以看到;POST 請求的請求參數是添加到 body 中,在 url 中不可見。

  2. 請求的 url 有長度限制,這個限制由瀏覽器和 web 服務器決定和設置的,例如 IE 瀏覽器對 URL 的最大限制爲 2083 個字符,如果超過這個數字,提交按鈕沒有任何反應,因爲 GET 請求的參數是添加到 URL 中,所以 GET 請求的 URL 的長度限制需要將請求參數長度也考慮進去。而 POST 請求不用考慮請求參數的長度。

  3. GET 請求產生一個數據包; POST 請求產生 2 個數據包,在火狐瀏覽器中,產生一個數據包,這個區別點在於瀏覽器的請求機制,先發送請求頭,再發送請求體,因爲 GET 沒有請求體,所以就發送一個數據包,而 POST 包含請求體,所以發送兩次數據包,但是由於火狐機制不同,所以發送一個數據包。

  4. GET 請求會被瀏覽器主動緩存下來,留下歷史記錄,而 POST 默認不會。

  5. GET 是冪等的,而 POST 不是 (冪等表示執行相同的操作,結果也是相同的)

  6. GET 是獲取數據,POST 是修改數據

狀態碼

「狀態碼由 3 位數字組成,第一位定義響應的類別」

1XX:指示信息,表示請求以接收,繼續處理

2XX:成功,表示請求已經被成功接收、理解、接受

3XX:狀態碼錶示客戶端請求的資源發送了變動,需要客戶端用新的 URL 重新發送請求獲取資源,也就是**「重定向」**。

301 和 302 都會在響應頭裏使用字段 Location,指明後續要跳轉的 URL,瀏覽器會自動重定向新的 URL。

4XX:狀態碼錶示客戶端發送的**「報文有誤」**,服務器無法處理,也就是錯誤碼的含義。

5XX:狀態碼錶示客戶端請求報文正確,但是**「服務器處理時內部發生了錯誤」**,屬於服務器端的錯誤碼。

「301 和 302 的區別」

301 重定向,指頁面永久性轉移,表示爲資源或頁面永久性地轉移到了另一個位置。

301 是 HTTP 協議中的一種狀態碼,當用戶或搜索引擎向服務器發出瀏覽請求時,服務器返回的 HTTP 數據流中頭信息中包含狀態碼 301 ,表示該資源已經永久改變了位置。

302 重定向是頁面暫時性轉移,搜索引擎會抓取新的內容而保存舊的網址並認爲新的網址只是暫時的。

HTTP1.1

「長連接」

HTTP 1.1 支持長連接

HTTP 1.0 規定瀏覽器與服務器只保持短暫的連接,瀏覽器的每次請求都需要與服務器建立一個 TCP 連接,服務器完成請求處理後立即斷開 TCP 連接,服務器不跟蹤每個客戶也不記錄過去的請求。

HTTP 1.1 則支持持久連接 Persistent Connection,並且默認使用,在同一個 TCP 的連接中可以傳送多個 HTTP 請求和響應,多個請求和響應可以重疊,多個請求和響應可以同時進行,更加多的請求頭和響應頭

HTTP 1.1 的持續連接,也需要增加新的請求頭來幫助實現,例如,Connection 請求頭的值爲 Keep-Alive 時,客戶端通知服務器返回本次請求結果後保持連接;Connection 請求頭的值爲 Close 時,客戶端通知服務器返回本次請求結果後關閉連接。

「管道網絡傳輸」

HTTP/1.1 採用了長連接的方式,這使得管道網絡傳輸成爲了可能。

即可在同一個 TCP 連接裏面,客戶端可以發起多個請求,只要第一個請求發出去了,不必等其回來,就可以發第二個請求出去,可以**「減少整體的響應時間。」**

舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個 TCP 連接裏面,先發送 A 請求,然後等待服務器做出迴應,收到後再發出 B 請求,管道機制則是允許瀏覽器同時發出 A 請求和 B 請求。

但是服務器還是按照**「順序」**,先回應 A 請求,完成後再回應 B 請求,要是 前面的迴應特別慢,後面就會有許多請求排隊等着。

「Host 字段」

在 HTTP1.0 中認爲每臺服務器都綁定一個唯一的 IP 地址,因此,請求消息中的 URL 並沒有傳遞主機名,但隨着虛擬主機技術的發展,在一臺物理服務器上可以存在多個虛擬主機,並且它們共享一個 IP 地址。

HTTP1.1 的請求消息和響應消息都應支持 Host 頭域,且請求消息中如果沒有 Host 頭域會報告一個錯誤(400 Bad Request)。

此外,服務器應該接受以絕對路徑標記的資源請求。

「100Status」

HTTP/1.1 加入了一個新的狀態碼 100。

客戶端事先發送一個只帶頭域的請求,如果服務器因爲權限拒絕了請求,就回送響應碼 401(Unauthorized);

如果服務器接收此請求就回送響應碼 100,客戶端就可以繼續發送帶實體的完整請求了。

100 狀態代碼的使用,允許客戶端在發 request 消息 body 之前先用 request header 試探一下 server,看 server 要不要接收 request body,再決定要不要發 request body。

「Chunked Transfer Coding」

HTTP/1.1 將發送方將消息分割成若干個任意大小的數據塊,每個數據塊在發送時都會附上塊的長度,最後用一個零長度的塊作爲消息結束的標誌。

這種方法允許發送方只緩衝消息的一個片段,避免緩衝整個消息帶來的過載。

「Cache」

HTTP/1.1 在 1.0 的基礎上加入了一些 Cache 的新特性,當緩存對象的 Age 超過 Expire 時變爲 Stable 對象,Cache 不需要直接拋棄 Stable 對象,而是與源服務器進行重新激活。

HTTP2.0

「HTTP2.0 和 HTTP1.X 相比的新特性」

HTTP/2 還在一定程度上改善了傳統的請求 - 應答工作模式,服務不再是被動地響應,也可以**「主動」**向客戶端發送消息。

舉例來說,在瀏覽器剛請求 HTML 的時候,就提前把可能會用到的 JS、CSS 文件等靜態資源主動發給客戶端,「減少延時的等待」,也就是服務器推送。

「數據流」

HTTP/2 的數據包不是按順序發送的,同一個連接裏面連續的數據包,可能屬於不同的迴應。

因此,必須要對數據包做標記,指出它屬於哪個迴應。

每個請求或迴應的所有數據包,稱爲一個數據流(Stream)。

每個數據流都標記着一個獨一無二的編號,其中規定客戶端發出的數據流編號爲奇數, 服務器發出的數據流編號爲偶數

客戶端還可以**「指定數據流的優先級」**。優先級高的請求,服務器就先響應該請求。

「HTTP2.0 的多路複用和 HTTP1.X 中的長連接複用有什麼區別」

HTTP3.0

「使用 UDP 協議」

HTTP/2 主要的問題在於:多個 HTTP 請求在複用一個 TCP 連接,下層的 TCP 協議是不知道有多少個 HTTP 請求的。

所以一旦發生了丟包現象,就會觸發 TCP 的重傳機制,這樣在一個 TCP 連接中的**「所有的 HTTP 請求都必須等待這個丟了的包被重傳回來」**。

這都是基於 TCP 傳輸層的問題,所以 「HTTP/3 把 HTTP 下層的 TCP 協議改成了 UDP!」

HTTPS

「HTTP 與 HTTPS 的區別」

HTTP 是明文傳輸協議,HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議,比 HTTP 協議安全

「工作原理」

HTTPS 協議會對傳輸的數據進行加密,而加密過程是使用了非對稱加密實現

HTTPS 的整體過程分爲證書驗證和數據傳輸階段,具體的交互過程如下:

數字證書

客戶端先向服務器端索要公鑰,然後用公鑰加密信息,服務器收到密文後,用自己的私鑰解密。

這就存在些問題,如何保證公鑰不被篡改和信任度?

所以這裏就需要藉助第三方權威機構 CA (數字證書認證機構),將**「服務器公鑰放在數字證書」**(由數字證書認證機構頒發)中,只要證書是可信的,公鑰就是可信的。

通過數字證書的方式保證服務器公鑰的身份,解決冒充的風險。

請求報文

「請求頭」

HTTP 請求報文由 3 部分組成 (請求行 + 請求頭 + 請求體)

「常見的 HTTP 報文頭屬性」

決定當前事務(三次握手和四次揮手)完成後,是否關閉網絡連接。

響應報文

響應報文與請求報文一樣,由三個部分組成 (響應行, 響應頭, 響應體)

「HTTP 響應報文屬性」

TCP

TCP 是一個傳輸層協議,提供可靠傳輸,支持全雙工,是一個連接導向的協議。

「雙工 / 單工」

在任何一個時刻,如果數據只能單向發送,就是單工。

如果在某個時刻數據可以向一個方向傳輸,也可以向另一個方向反方向傳輸,而且交替進行,叫作半雙工;半雙工需要至少 1 條線路。

如果任何時刻數據都可以雙向收發,這就是全雙工,全雙工需要大於 1 條線路。

TCP 是一個雙工協議,數據任何時候都可以雙向傳輸。

這就意味着客戶端和服務端可以平等地發送、接收信息。

「TCP 協議的主要特點」

「TCP 的可靠性原理」

可靠傳輸有如下兩個特點:

  1. 傳輸信道無差錯, 保證傳輸數據正確;

  2. 不管發送方以多快的速度發送數據, 接收方總是來得及處理收到的數據;

首先,採用三次握手來建立 TCP 連接,四次握手來釋放 TCP 連接,從而保證建立的傳輸信道是可靠的。

其次,TCP 採用了連續 ARQ 協議(回退 N(Go-back-N);超時自動重傳)來保證數據傳輸的正確性,使用滑動窗口協議來保證接方能夠及時處理所接收到的數據,進行流量控制。

最後,TCP 使用慢開始、擁塞避免、快重傳和快恢復來進行擁塞控制,避免網絡擁塞。

報文段

TCP 雖面向字節流,但傳送的數據單元爲報文段

報文段 = 首部 + 數據 2 部分

TCP 的全部功能體現在它首部中各字段的作用

  1. 首部前 20 個字符固定、後面有 4n 個字節是根據需而增加的選項

  2. 故 TCP 首部最小長度 = 20 字節

「端口」

源端口號和目地端口各佔 16 位兩個字節,也就是端口的範圍是2^16=65535

另外 1024 以下是系統保留的,從 1024-65535 是用戶使用的端口範圍

「seq 序號」:佔 4 字節,TCP 連接中傳送的字節流中的每個字節都按順序編號。

例如:一段報文的序號字段值是 107,攜帶的數據是 100 個字段,下一個報文段序號從 107+100=207 開始。

「ack 確認號」:4 個字節,是期望收到對方下一個報文段的第一個數據字節的序號。

例如:B 收到 A 發送的報文,其序號字段是 301,數據長度是 200 字節,表明 B 正確收到 A 發送的到序號 500 爲止的數據(301+200-1=500),B 期望收到 A 下一個數據序號是 501,B 發送給 A 的確認報文段中把 ack 確認號置爲 501。

「數據偏移」:頭部有可選字段,長度不固定,指出 TCP 報文段的數據起始處距離報文段的起始處有多遠。

「保留」:保留今後使用的,被標爲 1。

「控制位」:由 8 個標誌位組成。每個標誌位表示一個控制功能。

其中主要的 6 個:

「窗口」:滑動窗口大小,用來告知發送端接收端緩存大小,以此控制發送端發送數據的速率,從而達到流量控制。

「校驗和」:奇偶校驗,此校驗和是對整個的 TCP 報文段(包括 TCP 頭部和 TCP 數據),以 16 位進行計算所得,由發送端計算和存儲,接收端進行驗證。

「緊急指針」:只有控制位中的 URG 爲 1 時纔有效,指出本報文段中的緊急數據的字節數。

「選項」:其長度可變,定義其他的可選參數。

粘包與拆包

TCP 是面向字節流的協議,把上層應用層的數據看成字節流,所以它發送的不是固定大小的數據包,TCP 協議也沒有字段說明發送數據包的大小。

而且 TCP 不保證接受方應用程序收到的數據塊和發送應用程序發送的數據塊具有對應的大小關係

比如發送方應用程序交給發送方TCP 10 個數據塊,接受方 TCP 可能只用了 4 個數據塊就完整的把接受到的字節流交給了上層應用程序。

TCP 底層並不瞭解上層業務數據的具體含義,它會根據 TCP 緩衝區的實際情況進行包的劃分,所以在業務上認爲,一個完整的包可能會被 TCP 拆分成多個包進行發送,也有可能把多個小的包封裝成一個大的數據包發送,這就是所謂的 TCP 粘包和拆包問題

「TCP 粘包 / 拆包解決策略」

由於 TCP 無法理解上一層的業務數據特點,所以 TCP 是無法保證發送的數據包不發生粘包和拆包,這個問題只能通過上層的協議棧設計來解決,解決思路有一下幾種:

三次握手

「第一次握手」

客戶端將 TCP 報文標誌位SYN置爲 1,隨機產生一個序號值seq=J,保存在 TCP 首部的序列號字段裏,指明客戶端打算連接的服務器的端口,並將該數據包發送給服務器端,發送完畢後,客戶端進入SYN_SENT狀態,等待服務器端確認。

「第二次握手」

服務器端收到數據包後由標誌位SYN=1知道客戶端請求建立連接,服務器端將 TCP 報文標誌位 SYN 和 ACK 都置爲 1,ack=J+1,隨機產生一個序號值seq=K,並將該數據包發送給客戶端以確認連接請求,服務器端進入SYN_RCVD狀態。

「第三次握手」

客戶端收到確認後,檢查 ack 是否爲J+1,ACK 是否爲 1,如果正確則將標誌位 ACK 置爲 1,ack=K+1,並將該數據包發送給服務器端,服務器端檢查 ack 是否爲K+1,ACK 是否爲 1,如果正確則連接建立成功,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手,隨後客戶端與服務器端之間可以開始傳輸數據了。

「上面寫的 ack 和 ACK,不是同一個概念:」

「TCP 爲什麼三次握手而不是兩次握手」

「《計算機網絡》中是這樣說的:」

爲了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

在書中同時舉了一個例子,如下:

假如client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達server,本來這是一個早已失效的報文段,但server收到此失效的連接請求報文段後,就誤認爲是 client 再次發出的一個新的連接請求。

於是就向 client 發出確認報文段,同意建立連接,假設不採用**「三次握手」**,那麼只要 server 發出確認,新的連接就建立了,由於現在 client 並沒有發出建立連接的請求,因此不會理睬 server 的確認,也不會向 server 發送數據。

但 server 卻以爲新的連接已經建立,並一直等待client發來數據,這樣,server 的很多資源就白白浪費掉了。

採用**「三次握手」**的辦法可以防止上述現象發生,例如剛纔那種情況,client 不會向server的確認發出確認,server 由於收不到確認,就知道 client 並沒有要求建立連接。

「什麼是半連接隊列」

服務器第一次收到客戶端的 SYN 之後,就會處於 SYN_RCVD狀態,此時雙方還沒有完全建立其連接,服務器會把此種狀態下請求連接放在一個隊列裏,我們把這種隊列稱之爲**「半連接隊列」**。

當然還有一個**「全連接隊列」**,就是已經完成三次握手,建立起連接的就會放在全連接隊列中。如果隊列滿了就有可能會出現丟包現象。

補充一點關於**「SYN-ACK 重傳次數」**的問題:

服務器發送完 SYN-ACK 包,如果未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。

「三次握手過程中可以攜帶數據嗎」

其實第三次握手的時候,是可以攜帶數據的,也就是說,第一次、第二次握手不可以攜帶數據,而第三次握手是可以攜帶數據的。

假如第一次握手可以攜帶數據的話,如果有人要惡意攻擊服務器,那他每次都在第一次握手中的 SYN 報文中放入大量的數據,因爲攻擊者根本就不理服務器的接收、發送能力是否正常,然後瘋狂着重複發 SYN 報文的話,這會讓服務器花費很多時間、內存空間來接收這些報文。也就是說,第一次握手可以放數據的話,其中一個簡單的原因就是會讓服務器更加容易受到攻擊了。

而對於第三次的話,此時客戶端已經處於 established 狀態,也就是說,對於客戶端來說,他已經建立起連接了,並且也已經知道服務器的接收、發送能力是正常的了,所以能攜帶數據沒啥毛病。

四次揮手

揮手請求可以是 Client 端,也可以是 Server 端發起的,我們假設是 Client 端發起:

「爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?」

建立連接時因爲當 Server 端收到 Client 端的 SYN 連接請求報文後,可以直接發送 SYN+ACK 報文。其中 ACK 報文是用來應答的,SYN 報文是用來同步的。所以建立連接只需要三次握手。

由於 TCP 協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議,TCP 是全雙工模式。

這就意味着,關閉連接時,當 Client 端發出 FIN 報文段時,只是表示 Client 端告訴 Server 端數據已經發送完畢了。當 Server 端收到 FIN 報文並返回 ACK 報文段,表示它已經知道 Client 端沒有數據發送了,但是 Server 端還是可以發送數據到 Client 端的,所以 Server 很可能並不會立即關閉 SOCKET,直到 Server 端把數據也發送完畢。

當 Server 端也發送了 FIN 報文段時,這個時候就表示 Server 端也沒有數據要發送了,就會告訴 Client 端,我也沒有數據要發送了,之後彼此就會愉快的中斷這次 TCP 連接。

「爲什麼 TIME_WAIT 要等待 2MSL?」

MSL:報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間。

有以下兩個原因:

流量控制

「RTT 和 RTO」

RTT:發送一個數據包到收到對應的 ACK,所花費的時間

RTO:重傳時間間隔(TCP 在發送一個數據包後會啓動一個重傳定時器,RTO 即定時器的重傳時間)

開始預先算一個定時器時間,如果回覆 ACK,重傳定時器就自動失效,即不需要重傳;如果沒有回覆 ACK,RTO 定時器時間就到了,重傳。

RTO 是本次發送當前數據包所預估的超時時間,RTO 不是固定寫死的配置,是經過 RTT 計算出來的。

「滑動窗口」

TCP 的滑動窗口主要有兩個作用:

  1. 保證 TCP 的可靠性

  2. 保證 TCP 的流控特性

TCP 報文頭有個字段叫 Window,用於接收方通知發送方自己還有多少緩存區可以接收數據,發送方根據接收方的處理能力來發送數據,不會導致接收方處理不過來,這便是流量控制。

發送方都維持了一個連續的允許發送的幀的序號,稱爲發送窗口;同時,接收方也維持了一個連續的允許接收的幀的序號,稱爲接收窗口。

發送窗口和接收窗口的序號的上下界不一定要一樣,甚至大小也可以不同。

不同的滑動窗口協議窗口大小一般不同。

發送方窗口內的序列號代表了那些已經被髮送,但是還沒有被確認的幀,或者是那些可以被髮送的幀

滑動窗口由四部分組成每個字節的數據都有唯一順序的編碼,隨着時間發展,未確認部分與可以發送數據包編碼部分向右移動,形式滑動窗口

  1. 綠色:發送成功並已經 ACK 確認的數據

  2. 黃色:發送成功等待 ACK 確認的數據 (佔用滑動窗口大小)

  3. 紫色:滑動窗口剩餘大小可以發送的字節數量 (滑動窗口可用大小)

  4. 灰色:後續數據編碼

接收窗口的大小就是滑動窗口的最大值,數據傳輸過程中滑動窗口的可用大小是動態變化的。

但是還有這麼一點,滑動窗口的設計僅僅是考慮到了處理方的處理能力,但是沒有考慮到道路的通暢問題

就好像服務端可以處理 100M 數據,但是傳輸的數據 99M 都堵在路上了,這不就是導致道路阻塞了麼?這就需要另外一個設計**「擁塞避免」**

「流量控制的目的」

如果發送者發送數據過快,接收者來不及接收,那麼就會有分組丟失。

爲了避免分組丟失,控制發送者的發送速度,使得接收者來得及接收,這就是流量控制。

流量控制根本目的是防止分組丟失,它是構成 TCP 可靠性的一方面。

「如何實現流量控制」

由滑動窗口協議(連續 ARQ 協議)實現。滑動窗口協議既保證了分組無差錯、有序接收,也實現了流量控制。

主要的方式就是接收方返回的 ACK 中會包含自己的接收窗口的大小,並且利用大小來控制發送方的數據發送。

「流量控制引發的死鎖」

當發送者收到了一個窗口爲 0 的應答,發送者便停止發送,等待接收者的下一個應答。

但是如果這個窗口不爲 0 的應答在傳輸過程丟失,發送者一直等待下去,而接收者以爲發送者已經收到該應答,等待接收新數據,這樣雙方就相互等待,從而產生死鎖。

爲了避免流量控制引發的死鎖,TCP 使用了**「持續計時器」**。每當發送者收到一個零窗口的應答後就啓動該計時器。時間一到便主動發送報文詢問接收者的窗口大小。若接收者仍然返回零窗口,則重置該計時器繼續等待;若窗口不爲 0,則表示應答報文丟失了,此時重置發送窗口後開始發送,這樣就避免了死鎖的產生。

擁塞控制

「爲什麼要進行擁塞控制」

假設網絡已經出現擁塞,如果不處理擁塞,那麼延時增加,出現更多丟包,觸發發送方重傳數據,加劇擁塞情況,繼續惡性循環直至網絡癱瘓。

擁塞控制與流量控制的適應場景和目的均不同。

擁塞發生前,可避免流量過快增長拖垮網絡;擁塞發生時,唯一的選擇就是降低流量。

主要使用 4 種算法完成擁塞控制:

  1. 慢啓動

  2. 擁塞避免

  3. 快重傳算法

  4. 快速恢復算法

算法 1、2 適用於擁塞發生前,算法 3 適用於擁塞發生時,算法 4 適用於擁塞解決後(相當於擁塞發生前)。

「rwnd 與 cwnd」

rwnd(Receiver Window,接收者窗口)與cwnd(Congestion Window,擁塞窗口):

同時考慮流量控制與擁塞處理,則發送方窗口的大小不超過min{rwnd, cwnd}

「慢啓動算法」

慢開始算法的思路就是,不要一開始就發送大量的數據,先探測一下網絡的擁塞程度,也就是說由小到大逐漸增加擁塞窗口的大小。

這裏用報文段的個數作爲擁塞窗口的大小舉例說明慢開始算法,實際的擁塞窗口大小是以字節爲單位的。

一個傳輸輪次所經歷的時間其實就是往返時間 RTT,而且每經過一個傳輸輪次,擁塞窗口 cwnd 就加倍。

爲了防止 cwnd 增長過大引起網絡擁塞,還需設置一個慢開始門限 ssthresh 狀態變量。

ssthresh 的用法如下:

注意,這裏的慢並不是指 cwnd 的增長速率慢,而是指在 TCP 開始發送報文段時先設置 cwnd=1,然後逐漸增大,這當然比按照大的 cwnd 一下子把許多報文段突然注入到網絡中要慢得多。

「擁塞避免算法」

讓擁塞窗口 cwnd 緩慢地增大,即每經過一個往返時間 RTT 就把發送方的擁塞窗口 cwnd 加 1,而不是加倍。

這樣擁塞窗口 cwnd 按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多

無論是在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有按時收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因爲無法判定,所以都當做擁塞來處理),就把慢開始門限 ssthresh 設置爲出現擁塞時的發送窗口大小的一半(但不能小於 2)。

然後把擁塞窗口 cwnd 重新設置爲 1,執行慢開始算法。

這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。

「整個擁塞控制的流程:」

假定 cwnd=24 時,網絡出現超時(擁塞),則更新後的 ssthresh=12,cwnd 重新設置爲 1,並執行慢開始算法。

當 cwnd=12=ssthresh 時,改爲執行擁塞避免算法

注意:擁塞避免並非完全能夠避免了阻塞,而是使網絡比較不容易出現擁塞。

「快重傳算法」

快重傳要求接收方在收到一個失序的報文段後就立即發出重複確認(爲的是使發送方及早知道有報文段沒有到達對方,可提高網絡吞吐量約 20%)而不要等到自己發送數據時捎帶確認。

快重傳算法規定,發送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器時間到期

「快恢復算法」

快重傳配合使用的還有快恢復算法,有以下兩個要點:

考慮到如果網絡出現擁塞的話就不會收到好幾個重複的確認,所以發送方現在認爲網絡可能沒有出現擁塞。

所以此時不執行慢開始算法,而是將 cwnd 設置爲 ssthresh 減半後的值,然後執行擁塞避免算法,使 cwnd 緩慢增大。

Socket

即套接字,是應用層 與 TCP/IP 協議族通信的中間軟件抽象層,表現爲一個封裝了 TCP / IP 協議族 的編程接口(API)

Socket不是一種協議,而是一個編程調用接口(API),屬於傳輸層(主要解決數據如何在網絡中傳輸)

對用戶來說,只需調用 Socket 去組織數據,以符合指定的協議,即可通信

UDP

「UDP 協議特點」

「TCP 和 UDP 的區別」

「基於 TCP 和 UDP 的常用協議」

HTTP、HTTPS、FTP、TELNET、SMTP(簡單郵件傳輸協議) 協議基於可靠的 TCP 協議。

TFTP、DNS、DHCP、TFTP、SNMP(簡單網絡管理協議)、RIP 基於不可靠的 UDP 協議

報文段

UDP 的報文段共有 2 個字段:數據字段 + 首部字段

「UDP 報文中每個字段的含義如下:」

網絡層

MAC 地址

MAC 稱爲物理地址,也叫硬件地址,用來定義網絡設備的位置,MAC 地址是網卡出廠時設定的,是固定的(但可以通過在設備管理器中或註冊表等方式修改,同一網段內的 MAC 地址必須唯一)。

MAC 地址採用十六進制數表示,長度是 6 個字節(48 位),分爲前 24 位和後 24 位。

MAC 地址對應於 OSI 參考模型的第二層數據鏈路層,工作在數據鏈路層的交換機維護着計算機 MAC 地址和自身端口的數據庫,交換機根據收到的數據幀中的目的 MAC 地址字段來轉發數據幀。

IP 地址

常見的 IP 地址分爲 IPv4 與 IPv6 兩大類,當前廣泛應用的是 IPv4,目前 IPv4 幾乎耗盡,下一階段必然會進行版本升級到 IPv6;

IP 地址是以網絡號和主機號來標示網絡上的主機的,我們把網絡號相同的主機稱之爲本地網絡,網絡號不相同的主機稱之爲遠程網絡主機

本地網絡中的主機可以直接相互通信;遠程網絡中的主機要相互通信必須通過本地網關(Gateway)來傳遞轉發數據。

IP 地址對應於 OSI 參考模型的第三層網絡層,工作在網絡層的路由器根據目標 IP 和源 IP 來判斷是否屬於同一網段,如果是不同網段,則轉發數據包。

「IP 地址格式和表示」

IP 地址 (IPv4) 由 32 位二進制數組成,分爲 4 段(4 個字節),每一段爲 8 位二進制數(1 個字節)

每一段 8 位二進制,中間使用英文的標點符號.隔開

由於二進制數太長,爲了便於記憶和識別,把每一段 8 位二進制數轉成十進制,大小爲 0 至 255。

IP 地址的這種表示法叫做**「點分十進制表示法」**。

IP 地址表示爲:xxx.xxx.xxx.xxx

舉個栗子:210.21.196.6就是一個 IP 地址的表示。

計算機的 IP 地址由兩部分組成,一部分爲網絡標識,一部分爲主機標識,同一網段內的計算機網絡部分相同,主機部分不能同時重複出現。

**「路由器」連接不同網段,負責不同網段之間的數據轉發,「交換機」**連接的是同一網段的計算機。

通過設置網絡地址和主機地址,在互相連接的整個網絡中保證每臺主機的 IP 地址不會互相重疊,即 IP 地址具有了唯一性。

「IP 地址分類詳解」

IP 地址分 A、B、C、D、E 五類,其中 A、B、C 這三類是比較常用的 IP 地址,D、E 類爲特殊地址。

子網掩碼

「子網掩碼的概念及作用」

通過子網掩碼,才能表明一臺主機所在的子網與其他子網的關係,使網絡正常工作。

子網掩碼和 IP 地址做與運算,分離出 IP 地址中的網絡地址和主機地址,用於判斷該 IP 地址是在本地網絡上,還是在遠程網絡網上。

子網掩碼還用於將網絡進一步劃分爲若干子網,以避免主機過多而擁堵或過少而 IP 浪費。

「子網掩碼的組成」

同 IP 地址一樣,子網掩碼是由長度爲 32 位二進制數組成的一個地址。

子網掩碼 32 位與 IP 地址 32 位相對應,IP 地址如果某位是網絡地址,則子網掩碼爲 1,否則爲 0。

舉個栗子:如:11111111.11111111.11111111.00000000

左邊連續的 1 的個數代表網絡號的長度,(使用時必須是連續的,理論上也可以不連續),右邊連續的 0 的個數代表主機號的長度。

「爲什麼要使用子網掩碼」

兩臺主機要通信,首先要判斷是否處於同一網段,即網絡地址是否相同。

如果相同,那麼可以把數據包直接發送到目標主機,否則就需要路由網關將數據包轉發送到目的地。

可以這麼簡單的理解:A 主機要與 B 主機通信,A 和 B 各自的 IP 地址與 A 主機的子網掩碼進行 And 與運算,看得出的結果:

1、結果如果相同,則說明這兩臺主機是處於同一個網段,這樣 A 可以通過 ARP 廣播發現 B 的 MAC 地址,B 也可以發現 A 的 MAC 地址來實現正常通信。

2、如果結果不同,ARP 廣播會在本地網關終結,這時候 A 會把發給 B 的數據包先發給本地網關,網關再根據 B 主機的 IP 地址來查詢路由表,再將數據包繼續傳遞轉發,最終送達到目的地 B。

計算機的網關(Gateway)就是到其他網段的出口,也就是路由器接口 IP 地址。

路由器接口使用的 IP 地址可以是本網段中任何一個地址,不過通常使用該網段的第一個可用的地址或最後一個可用的地址,這是爲了儘可能避免和本網段中的主機地址衝突。

在如下拓撲圖示例中,A 與 B,C 與 D,都可以直接相互通信(都是屬於各自同一網段,不用經過路由器)

但是 A 與 C,A 與 D,B 與 C,B 與 D 它們之間不屬於同一網段,所以它們通信是要經過本地網關,然後路由器根據對方 IP 地址,在路由表中查找恰好有匹配到對方 IP 地址的直連路由,於是從另一邊網關接口轉發出去實現互連

「子網掩碼和 IP 地址的關係」

子網掩碼是用來判斷任意兩臺主機的 IP 地址是否屬於同一網絡的依據

拿雙方主機的 IP 地址和自己主機的子網掩碼做與運算,如結果爲同一網絡,就可以直接通信

「如何根據 IP 地址和子網掩碼,計算網絡地址:」

將 IP 地址與子網掩碼轉換成二進制數。

將二進制形式的 IP 地址與子網掩碼做與運算。

將得出的結果轉化爲十進制,便得到網絡地址。

網關

網關實質上是一個網絡通向其他網絡的 IP 地址。

比如有網絡 A 和網絡 B,網絡 A 的 IP 地址範圍爲192.168.1.1~192. 168.1.254,子網掩碼爲255.255.255.0

網絡 B 的 IP 地址範圍爲192.168.2.1~192.168.2.254,子網掩碼爲255.255.255.0

在沒有路由器的情況下,兩個網絡之間是不能進行 TCP/IP 通信的,即使是兩個網絡連接在同一臺交換機 (或集線器) 上,TCP/IP 協議也會根據子網掩碼(255.255.255.0) 判定兩個網絡中的主機處在不同的網絡裏。

而要實現這兩個網絡之間的通信,則必須通過網關。

如果網絡 A 中的主機發現數據包的目的主機不在本地網絡中,就把數據包轉發給它自己的網關,再由網關轉發給網絡 B 的網關,網絡 B 的網關再轉發給網絡 B 的某個主機。網絡 B 向網絡 A 轉發數據包的過程。

「所以說,只有設置好網關的 IP 地址,TCP/IP 協議才能實現不同網絡之間的相互通信。」

那麼這個 IP 地址是哪臺機器的 IP 地址呢?

網關的 IP 地址是具有路由功能的設備的 IP 地址,具有路由功能的設備有路由器、啓用了路由協議的服務器 (實質上相當於一臺路由器)、代理服務器 (也相當於一臺路由器)。

Ping

Ping 是我們測試網絡連接的常用指令。

它利用 ICMP 報文檢測網絡連接。

「假設 A ping B」

  1. ping 通知系統建立一個固定格式的 ICMP 請求數據包。

  2. ICMP 協議打包這個數據包和 B 的 IP 地址轉交給 IP 協議層

  3. IP 層協議將機器 B 的 IP 地址爲目的地址,本機的 IP 地址爲源地址,加上一些頭部必要的控制信息,構建一個 IP 數據包

  4. 獲取 B 的 MAC 地址,做這個操作首先機器 A 會判斷 B 是否在同一網段內,若 IP 層協議通過 B 的 IP 地址和自己的子網掩碼,發現它跟自己屬於同一網絡,就直接在本網絡查找這臺機器的 MAC,否則則通過路由器進行類似查找。

接下來是 ARP 協議根據 IP 地址查找 MAC 地址的過程:

  1. 數據鏈路層構建一個數據幀,目的地址是 IP 層傳過來的 MAC 地址,源地址是本機的 MAC 地址,再附加一些必要的控制信息,依據以太網的介質訪問規則將他們傳送出去

  2. 機器 B 收到這個數據幀後,先檢查目的地址,和本機 MAC 地址對比:

符合,接受,接收後檢查該數據幀,將 IP 數據包從幀中提取出來,交給本機的的 IP 地址協議層協議,IP 協議層檢查之後,將有用的信息提取給 ICMP 協議,後者處理,馬上構建一個 ICMP 應答包,發送給 A,其過程和主機 A 發送 ICMP 請求包到 B 的過程類似,但不用 ARP 廣播收取 A 的信息,因爲請求包中已經有足夠的信息用於 B 迴應 A。

若不符合,丟棄。

可以知道 PING 的過程即一段發送報文和接受確認報文的過程,在來回直接可以計算時延。

DNS

DNS 通過主機名,最終得到該主機名對應的 IP 地址的過程叫做域名解析(或主機名解析)。

「通俗的講」,我們更習慣於記住一個網站的名字,www.baidu.com,而不是記住它的 ip 地址,比如:167.23.10.2

「工作原理」

將主機域名轉換爲 ip 地址,屬於應用層協議,使用 UDP 傳輸。

第一步,客戶端向本地 DNS 服務器發送解析請求

第二步,本地 DNS 如有相應記錄會直接返回結果給客戶端,如沒有就向 DNS 根服務器發送請求

第三步, DSN 根服務器接收到請求,返回給本地服務器一個所查詢域的主域名服務器的地址

第四步,本地 dns 服務器再向返回的主域名服務器地址發送查詢請求

第五步,主域名服務器如有記錄就返回結果,沒有的話返回相關的下級域名服務器地址

第六步,本地 DNS 服務器繼續向接收到的地址進行查詢請求

第七步,下級域名服務器有相應記錄,返回結果

第八步,本地 dns 服務器將收到的返回地址發給客戶端,同時寫入自己的緩存,以便下次查詢

DNS 域名查詢實際上就是個不斷遞歸查詢的過程,直到查找到相應結果,需要注意的時,當找不到相應記錄,會返回空結果,而不是超時信息

DNS 記錄

A 記錄

定義www.example.com的ip地址
www.example.com.     IN     A     139.18.28.5;

上面的就是一條 DNS 記錄,純文本即可。

www.example.com 是要解析的域名。

A 是記錄的類型,A 記錄代表着這是一條用於解析 IPv4 地址的記錄。

從這條記錄可知,www.example.com的 IP 地址是 139.18.28.5。

CNAME

CNAME 用於定義域名的別名,如下面這條 DNS 記錄:

定義www.example.com的別名
a.example.com.          IN     CNAME   b.example.com.

這條 DNS 記錄定義了 a.example.comb.example.com 的別名。

用戶在瀏覽器中輸入 a.example.com 時候,通過 DNS 查詢會知道 a.example.comb.example.com 的別名,因此需要實際 IP 的時候,會去拿 b.example.com 的 A 記錄。

當你想把一個網站遷移到新域名,舊域名仍然保留的時候;還有當你想將自己的靜態資源放到 CDN 上的時候,CNAME 就非常有用。

AAAA 記錄

A 記錄是域名和 IPv4 地址的映射關係。和 A 記錄類似,AAAA 記錄則是域名和 IPv6 地址的映射關係。

MX 記錄

MX 記錄是郵件記錄,用來描述郵件服務器的域名。

在工作中,我們經常會發郵件到某個同事的郵箱。

比如說,發送一封郵件到 xiaoming@xiaoflyfish.com,那麼如何知道哪個 IP 地址是郵件服務器呢?

這個時候就可以用到下面這條 MX 記錄:

IN MX mail.xiaoflyfish.com

mail.xiaoflyfish.com 的 IP 地址可以通過查詢 mail.xiaoflyfishcom的 A 記錄和 AAAA 記錄獲得。

NS 記錄

NS 記錄是描述 DNS 服務器網址。從 DNS 的存儲結構上說,Name Server 中含有權威 DNS 服務的目錄。

也就是說,NS 記錄指定哪臺 Server 是回答 DNS 查詢的權威域名服務器。

當一個 DNS 查詢看到 NS 記錄的時候,會再去 NS 記錄配置的 DNS 服務器查詢,得到最終的記錄。如下面這個例子:

a.com.     IN      NS      ns1.a.com.
a.com.     IN      NS      ns2.a.com.

當解析 a.com 地址時,我們看到 a.com 有兩個 NS 記錄,所以確定最終 a.com 的記錄在 ns1.a.comns2.a.com 上。

從設計上看,ns1 和 ns2 是網站 a.com 提供的智能 DNS 服務器,可以提供負載均衡、分佈式 Sharding 等服務。

比如當一個北京的用戶想要訪問 a.com 的時候,ns1 看到這是一個北京的 IP 就返回一個離北京最近的機房 IP。

上面代碼中 a.com 配置了兩個 NS 記錄。

通常 NS 不會只有一個,這是爲了保證高可用,一個掛了另一個還能繼續服務。

通常數字小的 NS 記錄優先級更高,也就是 ns1 會優先於 ns2 響應。

配置了上面的 NS 記錄後,如果還配置了 a.com 的 A 記錄,那麼這個 A 記錄會被 NS 記錄覆蓋。

ARP 協議

ARP 即地址解析協議, 用於實現從 IP 地址到 MAC 地址的映射,即詢問目標 IP 對應的 MAC 地址。

「ARP 協議的工作過程」

首先,每個主機都會有自己的 ARP 緩存區中建立一個 ARP 列表,以表示 IP 地址和 MAC 地址之間的對應關係

當源主機要發送數據時,首先檢測 ARP 列表中是否對應 IP 地址的目的主機的 MAC 地址,如果有,則直接發送數據,如果沒有,就向本網段的所有主機發送 ARP 數據包

當本網絡的所有主機收到該 ARP 數據包時,首先檢查數據包中的 IP 地址是否是自己的 IP 地址,如果不是,則忽略該數據包,如果是,則首先從數據包中取出源主機的 IP 和 MAC 地址寫入到 ARP 列表中,如果存在,則覆蓋然後將自己的 MAC 地址寫入 ARP 響應包中,告訴源主機自己是它想要找的 MAC 地址

源主機收到 ARP 響應包後,將目的主機的 IP 和 MAC 地址寫入 ARP 列表,並利用此信息發送數據,如果源主機一直沒有收到 ARP 響應數據包,表示 ARP 查詢失敗。

數字簽名

網絡傳輸過程中需要經過很多中間節點,雖然數據無法被解密,但可能被篡改

數字簽名校驗數據的完整性

「數字簽名有兩種功效」

將一段文本先用 Hash 函數生成消息摘要,然後用發送者的私鑰加密生成數字簽名,與原文文一起傳送給接收者

接收者只有用發送者的公鑰才能解密被加密的摘要信息,然後用 HASH 函數對收到的原文產生一個摘要信息,與上一步得到的摘要信息對比。

如果相同,則說明收到的信息是完整的,在傳輸過程中沒有被修改,否則說明信息被修改過,因此數字簽名能夠驗證信息的完整性。

SQL 注入

SQL 注入的原理是將 SQL 代碼僞裝到輸入參數中,傳遞到服務器解析並執行的一種攻擊手法。

「SQL 注入攻擊實例」

比如,在一個登錄界面,要求輸入用戶名和密碼,可以這樣輸入實現免帳號登錄:

用戶名: ‘or 1 = 1 --
密 碼:

用戶一旦點擊登錄,如若沒有做特殊處理,那麼這個非法用戶就很得意的登陸進去了。

下面我們分析一下:從理論上說,後臺認證程序中會有如下的 SQL 語句:

String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”;

因此,當輸入了上面的用戶名和密碼,上面的 SQL 語句變成:

SELECT * FROM user_table WHERE username=’’or 1 = 1 –- and password=’’

分析上述 SQL 語句我們知道,username=‘ or 1=1 這個語句一定會成功;然後後面加兩個 -,這意味着註釋,它將後面的語句註釋,讓他們不起作用,這樣,上述語句永遠都能正確執行,用戶輕易騙過系統,獲取合法身份。

「應對方法」

預編譯

使用預編譯手段,綁定參數是最好的防 SQL 注入的方法。

目前許多的 ORM 框架及 JDBC 等都實現了 SQL 預編譯和參數綁定功能,攻擊者的惡意 SQL 會被當做 SQL 的參數而不是 SQL 命令被執行。

在 mybatis 的 mapper 文件中,對於傳遞的參數我們一般是使用 # 和$來獲取參數值。

當使用 #時,變量是佔位符,就是一般我們使用 java 的 jdbc 的 PrepareStatement 時的佔位符,所有可以防止 sql 注入;

當使用$時,變量就是直接追加在 sql 中,一般會有 sql 注入問題。

使用正則表達式過濾傳入的參數

過濾參數中含有的一些數據庫關鍵詞

加密算法

加密算法分**「對稱加密」** 和 **「非對稱加密」**,其中對稱加密算法的加密與解密密鑰相同,非對稱加密算法的加密密鑰與解密密鑰不同,此外,還有一類不需要密鑰的**「散列算法」**。

常見的 「對稱加密」 算法主要有 DES3DESAES 等,常見的 「非對稱算法」 主要有 RSADSA 等,「散列算法」 主要有 SHA-1MD5 等。

對稱加密

「對稱加密算法」 中,使用的密鑰只有一個,發送和接收雙方都使用這個密鑰對數據進行 「加密」「解密」

非對稱加密

「非對稱加密算法」,它需要兩個密鑰,一個稱爲 「公開密鑰」 (public key),即 「公鑰」,另一個稱爲 「私有密鑰」 (private key),即 「私鑰」

因爲 「加密」「解密」 使用的是兩個不同的密鑰,所以這種算法稱爲 「非對稱加密算法」

  1. 如果使用 「公鑰」 對數據 「進行加密」,只有用對應的 「私鑰」 才能 「進行解密」

  2. 如果使用 「私鑰」 對數據 「進行加密」,只有用對應的 「公鑰」 才能 「進行解密」

「例子」:甲方生成 「一對密鑰」 並將其中的一把作爲 「公鑰」 向其它人公開,得到該公鑰的 「乙方」 使用該密鑰對機密信息 「進行加密」 後再發送給甲方,甲方再使用自己保存的另一把 「專用密鑰」 (「私鑰」),對 「加密」 後的信息 「進行解密」

網絡攻擊

CSRF 和 XSS

「XSS:」

跨站腳本是一種網站應用程序的安全漏洞攻擊,是代碼注入的一種。

它允許惡意用戶將代碼注入到網頁上,其他用戶在觀看網頁時就會受到影響,這類攻擊通常包含了 HTML 以及用戶端腳本語言。

比如通過客戶端腳本語言(最常見如:JavaScript)

在一個論壇發帖中發佈一段惡意的 JavaScript 代碼就是腳本注入,如果這個代碼內容有請求外部服務器,那麼就叫做 XSS

「XSS 攻擊分類」

反射性 XSS 攻擊 (非持久性 XSS 攻擊)

例如,正常發送消息:

http://www.test.com/message.php?send=Hello,World!

接收者將會接收信息並顯示 HelloWorld;但是,非正常發送消息:

http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!

接收者接收消息顯示的時候將會彈出警告窗口!

持久性 XSS 攻擊 (留言板場景)

一般指 XSS 攻擊代碼存儲在網站數據庫,當一個頁面被用戶打開的時候執行。

也就是說,每當用戶使用瀏覽器打開指定頁面時,腳本便執行。

與非持久性 XSS 攻擊相比,持久性 XSS 攻擊危害性更大。

從名字就可以瞭解到,持久性 XSS 攻擊就是將攻擊代碼存入數據庫中,然後客戶端打開時就執行這些攻擊代碼。

例如,留言板表單中的表單域:

<input type="text" >

正常操作流程是:用戶是提交相應留言信息 — 將數據存儲到數據庫 — 其他用戶訪問留言板,應用去數據並顯示;

而非正常操作流程是攻擊者在 value 填寫:

<script>alert(‘foolish!’);</script> <!--或者html其他標籤(破壞樣式。。。)、一段攻擊型代碼-->

並將數據提交、存儲到數據庫中;當其他用戶取出數據顯示的時候,將會執行這些攻擊性代碼

「CSRF:」

跨站請求僞造,是一種挾制用戶在當前已登錄的 Web 應用程序上執行非本意的操作的攻擊方法。

比如冒充用戶發起請求(在用戶不知情的情況下),完成一些違背用戶意願的請求(如惡意發帖,刪帖,改密碼,發郵件等)。

DOS 攻擊

DOS:中文名稱是拒絕服務,該攻擊的效果是使得計算機或網絡無法提供正常的服務

「DOS 攻擊的原理:」

首先攻擊者向被攻擊的服務器發送大量的虛假 IP 請求,被攻擊者在收到請求後返回確認信息,等待攻擊者進行確認,該過程需要 TCP 的三次握手,由於攻擊者發送的請求信息是虛假的,所以服務器接收不到返回的確認信息,在一段時間內服務器會處與等待狀態,而分配給這次請求的資源卻被有被釋放

當被攻擊者等待一定的時間後,會因連接超時而斷開,這時攻擊者在次發送新的虛假信息請求,這樣最終服務器資源被耗盡,直到癱瘓

「DDOS:中文名稱是分佈式拒絕服務攻擊」

指的是攻擊者控制多臺主機同時向同一主機或網絡發起DOS攻擊

DRDoS 分佈反射式拒絕服務攻擊這是DDoS攻擊的變形

「DDOS 究竟如何攻擊」

目前最流行也是最好用的攻擊方法就是使用SYN-Flood進行攻擊,SYN-Flood 也就是 SYN 洪水攻擊

SYN-Flood 不會完成 TCP 三次握手的第三步,也就是不發送確認連接的信息給服務器,這樣,服務器無法完成第三次握手,但服務器不會立即放棄,服務器會不停的重試並等待一定的時間後放棄這個未完成的連接,這段時間叫做SYN timeout,這段時間大約 30 秒 - 2 分鐘左右。

若是一個用戶在連接時出現問題導致服務器的一個線程等待 1 分鐘並不是什麼大不了的問題,但是若有人用特殊的軟件大量模擬這種情況,那後果就可想而知了。一個服務器若是處理這些大量的半連接信息而消耗大量的系統資源和網絡帶寬,這樣服務器就不會再有空餘去處理普通用戶的正常請求 (因爲客戶的正常請求比率很小),這樣這個服務器就無法工作了,這種攻擊就叫做SYN-Flood攻擊

到目前爲止,進行 DDoS 攻擊的防禦還是比較困難的

首先,這種攻擊的特點是它利用了 TCP/IP 協議的漏洞,除非你不用 TCP/IP,纔有可能完全抵禦住 DDoS 攻擊

不過這不等於我們就沒有辦法阻擋 DDoS 攻擊,我們可以盡力來減少 DDoS 的攻擊

「下面就是一些防禦方法:」

  1. 關閉不必要的服務

  2. 限制同時打開的 SYN 半連接數目

  3. 縮短 SYN 半連接的 time out 時間

  4. 正確設置防火牆

  5. 禁止對主機的非開放服務的訪問

  6. 限制特定 IP 地址的訪問

  7. 啓用防火牆的防 DDoS 的屬性

Cookie 和 Session

Session 是**「基於 Cookie 實現」**的另一種記錄服務端和客戶端會話狀態的機制。

Session 是存儲在服務端,而 SessionId 會被存儲在客戶端的 Cookie 中。

Session 的**「認證過程」**:

  1. 客戶端第一次發送請求到服務端,服務端根據信息創建對應的 Session,並在響應頭返回 SessionID

  2. 客戶端接收到服務端返回的 SessionID 後,會將此信息存儲在 Cookie 上,同時會記錄這個 SessionID 屬於哪個域名

  3. 當客戶端再次訪問服務端時,請求會自動判斷該域名下是否存在 Cookie 信息,如果有則發送給服務端,服務端會從 Cookie 中拿到 SessionID,再根據 SessionID 找到對應的 Session,如果有對應的 Session 則通過,繼續執行請求,否則就中斷

「Cookie 和 Session 的區別」

  1. 安全性,因爲 Cookie 可以通過客戶端修改,而 Session 只能在服務端設置,所以安全性比 Cookie 高,一般會用於驗證用戶登錄狀態

  2. 適用性,Cookie 只能存儲字符串數據,而 Session 可以存儲任意類型數據

  3. 有效期,Cookie 可以設置任意時間有效,而 Session 一般失效時間短

常見面試題

「在瀏覽器地址欄鍵入 URL」

1.DNS 解析:瀏覽器會依據 URL 逐層查詢 DNS 服務器緩存,解析 URL 中的域名對應的 IP 地址,DNS 緩存從近到遠依次是瀏覽器緩存、系統緩存、路由器緩存、IPS 服務器緩存、域名服務器緩存、頂級域名服務器緩存。

從哪個緩存找到對應的 IP 直接返回,不再查詢後面的緩存。

2.TCP 連接:結合三次握手

  1. 發送 HTTP 請求:瀏覽器發出讀取文件的 HTTP 請求,該請求發送給服務器

  2. 服務器處理請求並返回 HTTP 報文:服務器對瀏覽器請求做出響應,把對應的帶有 HTML 文本的 HTTP 響應報文發送給瀏覽器

  3. 瀏覽器解析渲染頁面

  4. 連接結束:瀏覽器釋放 TCP 連接,該步驟即四次揮手。

第 5 步和第 6 步可以認爲是同時發生的,哪一步在前沒有特別的要求

推薦關注「Linux 愛好者」,提升 Linux 技能

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/NKyp-WgGkor-8k3-RP4Ynw