大家好,我是老三,開工大吉,虎年第一篇,面渣逆襲系列繼續!
這次給大家帶來了計算機網絡六十二問,三萬字,七十圖詳解,大概是全網最全的網絡面試題。
建議大家收藏了慢慢看,新的一年一定能夠跳槽加薪,虎年“豹”富!
基礎
1.說下計算機網絡體系結構
計算機網絡體系結構,一般有三種:OSI 七層模型、TCP/IP 四層模型、五層結構。
簡單說,OSI是一個理論上的網絡通信模型,TCP/IP是實際上的網絡通信模型,五層結構就是爲了介紹網絡原理而折中的網絡通信模型。
OSI 七層模型
OSI 七層模型是國際標準化組織(International Organization for Standardization)制定的一個用於計算機或通信系統間互聯的標準體系。
- 應用層:通過應用進程之間的交互來完成特定網絡應用,應用層協議定義的是應用進程間通信和交互的規則,常見的協議有:HTTP FTP SMTP SNMP DNS.
- 表示層:數據的表示、安全、壓縮。確保一個系統的應用層所發送的信息可以被另一個系統的應用層讀取。
- 會話層:建立、管理、終止會話,是用戶應用程序和網絡之間的接口。
- 運輸層:提供源端與目的端之間提供可靠的透明數據傳輸,傳輸層協議爲不同主機上運行的進程提供邏輯通信。
- 網絡層:將網絡地址翻譯成對應的物理地址,實現不同網絡之間的路徑選擇, 協議有 ICMP IGMP IP 等.
- 數據鏈路層:在物理層提供比特流服務的基礎上,建立相鄰結點之間的數據鏈路。
- 物理層:建立、維護、斷開物理連接。
TCP/IP 四層模型
-
應用層:對應於 OSI 參考模型的(應用層、表示層、會話層)。
-
傳輸層: 對應 OSI 的傳輸層,爲應用層實體提供端到端的通信功能,保證了數據包的順序傳送及數據的完整性。
-
網際層:對應於 OSI 參考模型的網絡層,主要解決主機到主機的通信問題。
-
網絡接口層:與 OSI 參考模型的數據鏈路層、物理層對應。
五層體系結構
-
應用層:對應於 OSI 參考模型的(應用層、表示層、會話層)。
-
傳輸層:對應 OSI 參考模型的的傳輸層
-
網絡層:對應 OSI 參考模型的的網絡層
-
數據鏈路層:對應 OSI 參考模型的的數據鏈路層
-
物理層:對應 OSI 參考模型的的物理層。
2.說一下每一層對應的網絡協議有哪些?
一張表格總結常見網絡協議:
3.那麼數據在各層之間是怎麼傳輸的呢?
對於發送方而言,從上層到下層層層包裝,對於接收方而言,從下層到上層,層層解開包裝。
- 發送方的應用進程向接收方的應用進程傳送數據
- AP先將數據交給本主機的應用層,應用層加上本層的控制信息H5就變成了下一層的數據單元
- 傳輸層收到這個數據單元后,加上本層的控制信息H4,再交給網絡層,成爲網絡層的數據單元
- 到了數據鏈路層,控制信息被分成兩部分,分別加到本層數據單元的首部(H2)和尾部(T2)
- 最後的物理層,進行比特流的傳輸
這個過程類似寫信,寫一封信,每到一層,就加一個信封,寫一些地址的信息。到了目的地之後,又一層層解封,傳向下一個目的地。
網絡綜合
4.從瀏覽器地址欄輸入 url 到顯示主頁的過程?
這道題,大概的過程比較簡單,但是有很多點可以細挖:DNS解析、TCP三次握手、HTTP報文格式、TCP四次揮手等等。
- DNS 解析:將域名解析成對應的 IP 地址。
- TCP連接:與服務器通過三次握手,建立 TCP 連接
- 向服務器發送 HTTP 請求
- 服務器處理請求,返回HTTp響應
- 瀏覽器解析並渲染頁面
- 斷開連接:TCP 四次揮手,連接結束
我們以輸入www.baidu.com 爲例:
各個過程都使用了哪些協議?
5.說說 DNS 的解析過程?
DNS,英文全稱是 domain name system,域名解析系統,它的作用也很明確,就是域名和 IP 相互映射。
DNS 的解析過程如下圖:
假設你要查詢 www.baidu.com 的 IP 地址:
- 首先會查找瀏覽器的緩存,看看是否能找到www.baidu.com對應的IP地址,找到就直接返回;否則進行下一步。
- 將請求發往給本地DNS服務器,如果查找到也直接返回,否則繼續進行下一步;
- 本地DNS服務器向根域名服務器發送請求,根域名服務器返回負責
com
的頂級域名服務器的IP地址的列表。 - 本地DNS服務器再向其中一個負責
com
的頂級域名服務器發送一個請求,返回負責baidu.com
的權限域名服務器的IP地址列表。 - 本地DNS服務器再向其中一個權限域名服務器發送一個請求,返回www.baidu.com所對應的IP地址。
6.說說 WebSocket 與 Socket 的區別?
- Socket 其實就是等於 IP 地址 + 端口 + 協議。
具體來說,Socket 是一套標準,它完成了對 TCP/IP 的高度封裝,屏蔽網絡細節,以方便開發者更好地進行網絡編程。
- WebSocket 是一個持久化的協議,它是伴隨 H5 而出的協議,用來解決 http 不支持持久化連接的問題。
- Socket 一個是網編編程的標準接口,而 WebSocket 則是應用層通信協議。
7.說一下你瞭解的端口及對應的服務?
HTTP
8.說說 HTTP 常用的狀態碼及其含義?
HTTP狀態碼首先應該知道個大概的分類:
- 1XX:信息性狀態碼
- 2XX:成功狀態碼
- 3XX:重定向狀態碼
- 4XX:客戶端錯誤狀態碼
- 5XX:服務端錯誤狀態碼
幾個常用的,面試之外,也應該記住:
之前寫過一篇:程序員五一被拉去相親,結果徹底搞懂了HTTP常用狀態碼,還比較有意思,可以看看。
說一下301和302的區別?
- 301:永久性移動,請求的資源已被永久移動到新位置。服務器返回此響應時,會返回新的資源地址。
- 302:臨時性性移動,服務器從另外的地址響應資源,但是客戶端還應該使用這個地址。
用一個比喻,301就是嫁人的新垣結衣,302就是有男朋友的長澤雅美。
9.HTTP 有哪些請求方式?
其中,POST、DELETE、PUT、GET的含義分別對應我們最熟悉的增、刪、改、查。
10.說⼀下 GET 和 POST 的區別?
可以從以下幾個方面來說明GET和POST的區別:
- 從 HTTP 報文層面來看,GET 請求將信息放在 URL,POST 將請求信息放在請求體中。這一點使得 GET 請求攜帶的數據量有限,因爲 URL 本身是有長度限制的,而 POST 請求的數據存放在報文體中,因此對大小沒有限制。而且從形式上看,GET 請求把數據放 URL 上不太安全,而 POST 請求把數據放在請求體裏想比較而言安全一些。
- 從數據庫層面來看,GET 符合冪等性和安全性,而 POST 請求不符合。這個其實和 GET/POST 請求的作用有關。按照 HTTP 的約定,GET 請求用於查看信息,不會改變服務器上的信息;而 POST 請求用來改變服務器上的信息。正因爲 GET 請求只查看信息,不改變信息,對數據庫的一次或多次操作獲得的結果是一致的,認爲它符合冪等性。安全性是指對數據庫操作沒有改變數據庫中的數據。
- 從其他層面來看,GET 請求能夠被緩存,GET 請求能夠保存在瀏覽器的瀏覽記錄裏,GET 請求的 URL 能夠保存爲瀏覽器書籤。這些都是 POST 請求所不具備的。緩存是 GET 請求被廣泛應用的根本,他能夠被緩存也是因爲它的冪等性和安全性,除了返回結果沒有其他多餘的動作,因此絕大部分的 GET 請求都被 CDN 緩存起來了,大大減少了 Web 服務器的負擔。
11.GET 的長度限制是多少?
HTTP中的GET方法是通過URL傳遞數據的,但是URL本身其實並沒有對數據的長度進行限制,真正限制GET長度的是瀏覽器。
例如IE瀏覽器對URL的最大限制是2000多個字符,大概2kb左右,像Chrome、Firefox等瀏覽器支持的URL字符數更多,其中FireFox中URL的最大長度限制是65536個字符,Chrome則是8182個字符。
這個長度限制也不是針對數據部分,而是針對整個URL。
12.HTTP 請求的過程與原理?
HTTP協議定義了瀏覽器怎麼向服務器請求文檔,以及服務器怎麼把文檔傳給瀏覽器。
- 每個服務器都有一個進程,它不斷監聽TCP的端口80,以便發現是否有瀏覽器向它發出連接建立請求
- 監聽到連接請求,就會建立TCP連接
- 瀏覽器向服務器發出瀏覽某個頁面的請求,服務器接着就返回所請求的頁面作爲響應
- 最後,釋放TCP連接
在瀏覽器和服務器之間的請求和響應的交互,必須按照規定的格式和遵循一定的規則,這些格式和規則就是超文本傳輸協議HTTP。
PS:這道題和上面瀏覽器輸入網址發生了什麼那道題大差不差。
13.說一下HTTP的報文結構?
HTTP報文有兩種,HTTP請求報文和HTTP響應報文:
HTTP請求報文
HTTP 請求報文的格式如下:
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP 請求報文的第一行叫做請求行,後面的行叫做首部行,首部行後還可以跟一個實體主體。請求首部之後有一個空行,這個空行不能省略,它用來劃分首部與實體。
請求行包含三個字段:
- 方法字段:包括POST、GET等請方法。
- URL 字段
- HTTP 版本字段。
HTTP 響應報文
HTTP 響應報文的格式如下:
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
HTTP 響應報文的第一行叫做狀態行,後面的行是首部行,最後是實體主體。
- 狀態行包含了三個字段:協議版本字段、狀態碼和相應的狀態信息。
- 實體部分是報文的主要部分,它包含了所請求的對象。
- 首部行首部可以分爲四種首部,請求首部、響應首部、通用首部和實體首部。通用首部和實體首部在請求報文和響應報文中都可以設置,區別在於請求首部和響應首部。
- 常見的請求首部有 Accept 可接收媒體資源的類型、Accept-Charset 可接收的字符集、Host 請求的主機名。
- 常見的響應首部有 ETag 資源的匹配信息,Location 客戶端重定向的 URI。
- 常見的通用首部有 Cache-Control 控制緩存策略、Connection 管理持久連接。
- 常見的實體首部有 Content-Length 實體主體的大小、Expires 實體主體的過期時間、Last-Modified 資源的最後修改時間。
14.URI 和 URL 有什麼區別?
-
URI,統一資源標識符(Uniform Resource Identifier, URI),標識的是Web上每一種可用的資源,如 HTML文檔、圖像、視頻片段、程序等都是由一個URI進行標識的。
-
URL,統一資源定位符(Uniform Resource Location),它是URI的一種子集,主要作用是提供資源的路徑。
它們的主要區別在於,URL除了提供了資源的標識,還提供了資源訪問的方式。這麼比喻,URI 像是身份證,可以唯一標識一個人,而 URL 更像一個住址,可以通過 URL 找到這個人——人類住址協議://地球/中國/北京市/海淀區/xx職業技術學院/14號宿舍樓/525號寢/張三.男。
15.說下 HTTP/1.0,1.1,2.0 的區別?
關鍵需要記住 HTTP/1.0 默認是短連接,可以強制開啓,HTTP/1.1 默認長連接,HTTP/2.0 採用多路複用。
HTTP/1.0
- 默認使用短連接,每次請求都需要建立一個 TCP 連接。它可以設置
Connection: keep-alive
這個字段,強制開啓長連接。
HTTP/1.1
-
引入了持久連接,即 TCP 連接默認不關閉,可以被多個請求複用。
-
分塊傳輸編碼,即服務端每產生一塊數據,就發送一塊,用” 流模式” 取代” 緩存模式”。
-
管道機制,即在同一個 TCP 連接裏面,客戶端可以同時發送多個請求。
HTTP/2.0
- 二進制協議,1.1 版本的頭信息是文本(ASCII 編碼),數據體可以是文本或者二進制;2.0 中,頭信息和數據體都是二進制。
- 完全多路複用,在一個連接裏,客戶端和瀏覽器都可以同時發送多個請求或迴應,而且不用按照順序一一對應。
- 報頭壓縮,HTTP 協議不帶有狀態,每次請求都必須附上所有信息。Http/2.0 引入了頭信息壓縮機制,使用 gzip 或 compress 壓縮後再發送。
- 服務端推送,允許服務器未經請求,主動向客戶端發送資源。
16.HTTP/3瞭解嗎?
HTTP/3主要有兩大變化,傳輸層基於UDP、使用QUIC保證UDP可靠性。
HTTP/2存在的一些問題,比如重傳等等,都是由於TCP本身的特性導致的,所以HTTP/3在QUIC的基礎上進行發展而來,QUIC(Quick UDP Connections)直譯爲快速UDP網絡連接,底層使用UDP進行數據傳輸。
HTTP/3主要有這些特點:
- 使用UDP作爲傳輸層進行通信
- 在UDP的基礎上QUIC協議保證了HTTP/3的安全性,在傳輸的過程中就完成了TLS加密握手
- HTTPS 要建⽴⼀個連接,要花費 6 次交互,先是建⽴三次握⼿,然後是 TLS/1.3 的三次握⼿。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合併成了 3 次,減少了交互次數。
- QUIC 有⾃⼰的⼀套機制可以保證傳輸的可靠性的。當某個流發⽣丟包時,只會阻塞這個流,其他流不會受到影響。
我們拿一張圖看一下HTTP協議的變遷:
17.HTTP 如何實現長連接?在什麼時候會超時?
什麼是 HTTP 的長連接?
-
HTTP 分爲長連接和短連接,本質上說的是 TCP 的長短連接。TCP 連接是一個雙向的通道,它是可以保持一段時間不關閉的,因此 TCP 連接才具有真正的長連接和短連接這一說法。
-
TCP 長連接可以複用一個 TCP 連接,來發起多次的 HTTP 請求,這樣就可以減少資源消耗,比如一次請求 HTML,如果是短連接的話,可能還需要請求後續的 JS/CSS。
如何設置長連接?
通過在頭部(請求和響應頭)設置 Connection 字段指定爲keep-alive
,HTTP/1.0 協議支持,但是是默認關閉的,從 HTTP/1.1 以後,連接默認都是長連接。
在什麼時候會超時呢?
-
HTTP 一般會有 httpd 守護進程,裏面可以設置 keep-alive timeout,當 tcp 連接閒置超過這個時間就會關閉,也可以在 HTTP 的 header 裏面設置超時時間
-
TCP 的 keep-alive 包含三個參數,支持在系統內核的 net.ipv4 裏面設置;當 TCP 連接之後,閒置了 tcp_keepalive_time,則會發生偵測包,如果沒有收到對方的 ACK,那麼會每隔 tcp_keepalive_intvl 再發一次,直到發送了 tcp_keepalive_probes,就會丟棄該連接。
1. tcp_keepalive_intvl = 15
2. tcp_keepalive_probes = 5
3. tcp_keepalive_time = 1800
18.說說HTTP 與 HTTPS 有哪些區別?
-
HTTP 是超⽂本傳輸協議,信息是明⽂傳輸,存在安全⻛險的問題。HTTPS 則解決 HTTP 不安全的缺陷,在TCP 和 HTTP ⽹絡層之間加⼊了 SSL/TLS 安全協議,使得報⽂能夠加密傳輸。
-
HTTP 連接建⽴相對簡單, TCP 三次握⼿之後便可進⾏ HTTP 的報⽂傳輸。⽽ HTTPS 在 TCP 三次握⼿之後,還需進⾏ SSL/TLS 的握⼿過程,纔可進⼊加密報⽂傳輸。
-
HTTP 的端⼝號是 80,HTTPS 的端⼝號是 443。
-
HTTPS 協議需要向 CA(證書權威機構)申請數字證書,來保證服務器的身份是可信的。
19.爲什麼要用HTTPS?解決了哪些問題?
因爲HTTP 是明⽂傳輸,存在安全上的風險:
竊聽⻛險,⽐如通信鏈路上可以獲取通信內容,用戶賬號被盜。
篡改⻛險,⽐如強制植⼊垃圾⼴告,視覺污染。
冒充⻛險,⽐如冒充淘寶⽹站,用戶金錢損失。
所以引入了HTTPS,HTTPS 在 HTTP 與 TCP 層之間加⼊了 SSL/TLS 協議,可以很好的解決了這些風險:
-
信息加密:交互信息⽆法被竊取。
-
校驗機制:⽆法篡改通信內容,篡改了就不能正常顯示。
-
身份證書:能證明淘寶是真淘寶。
所以SSL/TLS 協議是能保證通信是安全的。
20.HTTPS工作流程是怎樣的?
這道題有幾個要點:公私鑰、數字證書、加密、對稱加密、非對稱加密。
HTTPS 主要工作流程:
- 客戶端發起 HTTPS 請求,連接到服務端的 443 端口。
- 服務端有一套數字證書(證書內容有公鑰、證書頒發機構、失效日期等)。
- 服務端將自己的數字證書發送給客戶端(公鑰在證書裏面,私鑰由服務器持有)。
- 客戶端收到數字證書之後,會驗證證書的合法性。如果證書驗證通過,就會生成一個隨機的對稱密鑰,用證書的公鑰加密。
- 客戶端將公鑰加密後的密鑰發送到服務器。
- 服務器接收到客戶端發來的密文密鑰之後,用自己之前保留的私鑰對其進行非對稱解密,解密之後就得到客戶端的密鑰,然後用客戶端密鑰對返回數據進行對稱加密,醬紫傳輸的數據都是密文啦。
- 服務器將加密後的密文返回到客戶端。
- 客戶端收到後,用自己的密鑰對其進行對稱解密,得到服務器返回的數據。
這裏還畫了一張更詳盡的圖:
21.客戶端怎麼去校驗證書的合法性?
首先,服務端的證書從哪來的呢?
爲了讓服務端的公鑰被⼤家信任,服務端的證書都是由 CA (Certificate Authority,證書認證機構)簽名的,CA就是⽹絡世界⾥的公安局、公證中⼼,具有極⾼的可信度,所以由它來給各個公鑰簽名,信任的⼀⽅簽發的證書,那必然證書也是被信任的。
CA 簽發證書的過程,如上圖左邊部分:
-
⾸先 CA 會把持有者的公鑰、⽤途、頒發者、有效時間等信息打成⼀個包,然後對這些信息進⾏ Hash 計算,得到⼀個 Hash 值;
-
然後 CA 會使⽤⾃⼰的私鑰將該 Hash 值加密,⽣成 Certificate Signature,也就是 CA 對證書做了簽名;
-
最後將 Certificate Signature 添加在⽂件證書上,形成數字證書;
客戶端校驗服務端的數字證書的過程,如上圖右邊部分:
- ⾸先客戶端會使⽤同樣的 Hash 算法獲取該證書的 Hash 值 H1;
- 通常瀏覽器和操作系統中集成了 CA 的公鑰信息,瀏覽器收到證書後可以使⽤ CA 的公鑰解密 Certificate
- Signature 內容,得到⼀個 Hash 值 H2 ;
- 最後⽐較 H1 和 H2,如果值相同,則爲可信賴的證書,否則則認爲證書不可信。
假如在HTTPS的通信過程中,中間人篡改了證書原文,由於他沒有CA機構的私鑰,所以CA公鑰解密的內容就不一致。
22.如何理解 HTTP 協議是無狀態的?
這個無狀態
的的狀態
值的是什麼?是客戶端的狀態,所以字面意思,就是HTTP協議中服務端不會保存客戶端的任何信息。
比如當瀏覽器第一次發送請求給服務器時,服務器響應了;如果同個瀏覽器發起第二次請求給服務器時,它還是會響應,但是呢,服務器不知道你就是剛纔的那個瀏覽器。
那有什麼辦法記錄狀態呢?
主要有兩個辦法,Session和Cookie。
23.說說Session 和 Cookie 有什麼聯繫和區別?
先來看看什麼是 Session 和 Cookie :
- Cookie 是保存在客戶端的一小塊文本串的數據。客戶端向服務器發起請求時,服務端會向客戶端發送一個 Cookie,客戶端就把 Cookie 保存起來。在客戶端下次向同一服務器再發起請求時,Cookie 被攜帶發送到服務器。服務端可以根據這個Cookie判斷用戶的身份和狀態。
- Session 指的就是服務器和客戶端一次會話的過程。它是另一種記錄客戶狀態的機制。不同的是cookie保存在客戶端瀏覽器中,而session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上,這就是session。客戶端瀏覽器再次訪問時只需要從該session中查找用戶的狀態。
Session 和 Cookie 到底有什麼不同呢?
-
存儲位置不一樣,Cookie 保存在客戶端,Session 保存在服務器端。
-
存儲數據類型不一樣,Cookie 只能保存ASCII,Session可以存任意數據類型,一般情況下我們可以在 Session 中保持一些常用變量信息,比如說 UserId 等。
-
有效期不同,Cookie 可設置爲長時間保持,比如我們經常使用的默認登錄功能,Session 一般有效時間較短,客戶端關閉或者 Session 超時都會失效。
-
隱私策略不同,Cookie 存儲在客戶端,比較容易遭到不法獲取,早期有人將用戶的登錄名和密碼存儲在 Cookie 中導致信息被竊取;Session 存儲在服務端,安全性相對 Cookie 要好一些。
-
存儲大小不同, 單個Cookie保存的數據不能超過4K,Session可存儲數據遠高於 Cookie。
Session 和 Cookie有什麼關聯呢?
可以使用Cookie記錄Session的標識。
- 用戶第一次請求服務器時,服務器根據用戶提交的信息,創建對應的 Session,請求返回時將此 Session 的唯一標識信息 SessionID 返回給瀏覽器,瀏覽器接收到服務器返回的 SessionID 信息後,會將此信息存入 Cookie 中,同時 Cookie 記錄此 SessionID 是屬於哪個域名。
- 當用戶第二次訪問服務器時,請求會自動判斷此域名下是否存在 Cookie 信息,如果存在,則自動將 Cookie 信息也發送給服務端,服務端會從 Cookie 中獲取 SessionID,再根據 SessionID 查找對應的 Session 信息,如果沒有找到,說明用戶沒有登錄或者登錄失效,如果找到 Session 證明用戶已經登錄可執行後面操作。
分佈式環境下Session怎麼處理呢?
分佈式環境下,客戶端請求經過負載均衡,可能會分配到不同的服務器上,假如一個用戶的請求兩次沒有落到同一臺服務器上,那麼在新的服務器上就沒有記錄用戶狀態的Session。
這時候怎麼辦呢?
可以使用Redis等分佈式緩存來存儲Session,在多臺服務器之間共享。
客戶端無法使用Cookie怎麼辦?
有可能客戶端無法使用Cookie,比如瀏覽器禁用Cookie,或者客戶端是安卓、IOS等等。
這時候怎麼辦?SessionID怎麼存?怎麼傳給服務端呢?
首先是SessionID的存儲,可以使用客戶端的本地存儲,比如瀏覽器的sessionStorage。
接下來怎麼傳呢?
- 拼接到URL裏:直接把SessionID作爲URL的請求參數
- 放到請求頭裏:把SessionID放到請求的Header裏,比較常用。
TCP
24.詳細說一下 TCP 的三次握手機制
PS:TCP三次握手是最重要的知識點,一定要熟悉到問到即送分。
TCP提供面向連接的服務,在傳送數據前必須建立連接,TCP連接是通過三次握手建立的。
三次握手的過程:
- 最開始,客戶端和服務端都處於CLOSE狀態,服務端監聽客戶端的請求,進入LISTEN狀態
- 客戶端端發送連接請求,第一次握手 (SYN=1, seq=x),發送完畢後,客戶端就進入 SYN_SENT 狀態
- 服務端確認連接,第二次握手 (SYN=1, ACK=1, seq=y, ACKnum=x+1), 發送完畢後,服務器端就進入 SYN_RCV 狀態。
- 客戶端收到服務端的確認之後,再次向服務端確認,這就是**第三次握手 **(ACK=1,ACKnum=y+1),發送完畢後,客戶端進入 ESTABLISHED 狀態,當服務器端接收到這個包時,也進入 ESTABLISHED 狀態。
TCP三次握手通俗比喻:
在二十年前的農村,電話沒有普及,手機就更不用說了,所以,通信基本靠吼。
老張和老王是鄰居,這天老張下地了,結果家裏有事,熱心的鄰居老王趕緊跑到村口,開始叫喚老王。
-
老王:老張唉!我是老王,你能聽到嗎?
-
老張一聽,是老王的聲音:老王老王,我是老張,我能聽到,你能聽到嗎?
-
老王一聽,嗯,沒錯,是老張:老張,我聽到了,我有事要跟你說。
"你老婆要生了,趕緊回家吧!"
老張風風火火地趕回家,老婆順利地生了個帶把的大胖小子。握手的故事充滿了幸福和美滿。
25.TCP 握手爲什麼是三次,爲什麼不能是兩次?不能是四次?
爲什麼不能是兩次?
- 爲了防止服務器端開啓一些無用的連接增加服務器開銷
- 防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。
由於網絡傳輸是有延時的(要通過網絡光纖和各種中間代理服務器),在傳輸的過程中,比如客戶端發起了 SYN=1 的第一次握手。
如果服務器端就直接創建了這個連接並返回包含 SYN、ACK 和 Seq 等內容的數據包給客戶端,這個數據包因爲網絡傳輸的原因丟失了,丟失之後客戶端就一直沒有接收到服務器返回的數據包。
如果沒有第三次握手告訴服務器端客戶端收的到服務器端傳輸的數據的話,服務器端是不知道客戶端有沒有接收到服務器端返回的信息的。
服務端就認爲這個連接是可用的,端口就一直開着,等到客戶端因超時重新發出請求時,服務器就會重新開啓一個端口連接。這樣一來,就會有很多無效的連接端口白白地開着,導致資源的浪費。
還有一種情況是已經失效的客戶端發出的請求信息,由於某種原因傳輸到了服務器端,服務器端以爲是客戶端發出的有效請求,接收後產生錯誤。
所以我們需要“第三次握手”來確認這個過程:
通過第三次握手的數據告訴服務端,客戶端有沒有收到服務器“第二次握手”時傳過去的數據,以及這個連接的序號是不是有效的。若發送的這個數據是“收到且沒有問題
”的信息,接收後服務器就正常建立 TCP 連接,否則建立 TCP 連接失敗,服務器關閉連接端口。由此減少服務器開銷和接收到失效請求發生的錯誤。
爲什麼不是四次?
簡單說,就是三次揮手已經足夠創建可靠的連接,沒有必要再多一次握手導致花費更多的時間建立連接。
26.三次握手中每一次沒收到報文會發生什麼情況?
-
第一次握手服務端未收到SYN報文
服務端不會進行任何的動作,而客戶端由於一段時間內沒有收到服務端發來的確認報文,等待一段時間後會重新發送SYN報文,如果仍然沒有迴應,會重複這個過程,直到發送次數超過最大重傳次數限制,就會返回連接建立失敗。
-
第二次握手客戶端未收到服務端響應的ACK報文
客戶端會繼續重傳,直到次數限制;而服務端此時會阻塞在accept()處,等待客戶端發送ACK報文
-
第三次握手服務端爲收到客戶端發送過來的ACK報文
服務端同樣會採用類似客戶端的超時重傳機制,如果重試次數超過限制,則accept()調用返回-1,服務端建立連接失敗;而此時客戶端認爲自己已經建立連接成功,因此開始向服務端發送數據,但是服務端的accept()系統調用已經返回,此時不在監聽狀態,因此服務端接收到客戶端發送來的數據時會發送RST報文給客戶端,消除客戶端單方面建立連接的狀態。
27.第二次握手傳回了 ACK,爲什麼還要傳回 SYN?
ACK是爲了告訴客戶端傳來的數據已經接收無誤。
而傳回SYN是爲了告訴客戶端,服務端響應的確實是客戶端發送的報文。
28.第3次握手可以攜帶數據嗎?
第3次握手是可以攜帶數據的。
此時客戶端已經處於ESTABLISHED狀態。對於客戶端來說,它已經建立連接成功,並且確認服務端的接收和發送能力是正常的。
第一次握手不能攜帶數據是出於安全的考慮,因爲如果允許攜帶數據,攻擊者每次在SYN報文中攜帶大量數據,就會導致服務端消耗更多的時間和空間去處理這些報文,會造成CPU和內存的消耗。
29.說說半連接隊列和 SYN Flood 攻擊的關係?
什麼是半連接隊列?
TCP 進入三次握手前,服務端會從 CLOSED 狀態變爲 LISTEN 狀態, 同時在內部創建了兩個隊列:半連接隊列(SYN 隊列)和全連接隊列(ACCEPT 隊列)。
顧名思義,半連接隊列存放的是三次握手未完成的連接,全連接隊列存放的是完成三次握手的連接。
- TCP 三次握手時,客戶端發送 SYN 到服務端,服務端收到之後,便回覆 ACK 和 SYN,狀態由 LISTEN 變爲 SYN_RCVD,此時這個連接就被推入了 SYN 隊列,即半連接隊列。
- 當客戶端回覆 ACK, 服務端接收後,三次握手就完成了。這時連接會等待被具體的應用取走,在被取走之前,它被推入 ACCEPT 隊列,即全連接隊列。
什麼是SYN Flood ?
SYN Flood 是一種典型的 DDos 攻擊,它在短時間內,僞造不存在的 IP 地址, 向服務器發送大量SYN 報文。當服務器回覆 SYN+ACK 報文後,不會收到 ACK 迴應報文,那麼SYN隊列裏的連接舊不會出對隊,久⽽久之就會佔滿服務端的 SYN 接收隊列(半連接隊列),使得服務器不能爲正常⽤戶服務。
那有什麼應對方案呢?
主要有 syn cookie 和 SYN Proxy 防火牆等。
-
syn cookie:在收到 SYN 包後,服務器根據一定的方法,以數據包的源地址、端口等信息爲參數計算出一個 cookie 值作爲自己的 SYNACK 包的序列號,回覆 SYN+ACK 後,服務器並不立即分配資源進行處理,等收到發送方的 ACK 包後,重新根據數據包的源地址、端口計算該包中的確認序列號是否正確,如果正確則建立連接,否則丟棄該包。
-
SYN Proxy 防火牆:服務器防火牆會對收到的每一個 SYN 報文進行代理和迴應,並保持半連接。等發送方將 ACK 包返回後,再重新構造 SYN 包發到服務器,建立真正的 TCP 連接。
30.說說 TCP 四次揮手的過程?
PS:問完三次握手,常常也會順道問問四次揮手,所以也是必須掌握知識點。
TCP 四次揮手過程:
-
數據傳輸結束之後,通信雙方都可以主動發起斷開連接請求,這裏假定客戶端發起
-
客戶端發送釋放連接報文,第一次揮手 (FIN=1,seq=u),發送完畢後,客戶端進入 FIN_WAIT_1 狀態。
-
服務端發送確認報文,第二次揮手 (ACK=1,ack=u+1,seq =v),發送完畢後,服務器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包之後,進入 FIN_WAIT_2 狀態。
-
服務端發送釋放連接報文,第三次揮手 (FIN=1,ACK1,seq=w,ack=u+1),發送完畢後,服務器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個 ACK。
-
客戶端發送確認報文,第四次揮手 (ACK=1,seq=u+1,ack=w+1),客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入 TIME_WAIT 狀態,等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)之後,沒有收到服務器端的 ACK ,認爲服務器端已經正常關閉連接,於是自己也關閉連接,進入 CLOSED 狀態。服務器端接收到這個確認包之後,關閉連接,進入 CLOSED 狀態。
大白話說四次揮手:
假如單身狗博主有一個女朋友—由於博主上班九九六,下班肝博客,導致沒有時間陪女朋友,女朋友忍無可忍。
- 女朋友:狗男人,最近你都不理我,你是不是不愛我了?你是不是外面有別的狗子了?我要和你分手?
- 沙雕博主一愣,怒火攻心:分手就分手,不陪你鬧了,等我把東西收拾收拾。
沙雕博主小心翼翼地裝起了自己的青軸機械鍵盤。
- 哼,蠢女人,我已經收拾完了,我先滾爲敬,再見!
- 女朋友:滾,滾的遠遠的,越遠越好,我一輩子都不想再見到你。
揮手的故事總充滿了悲傷和遺憾!
31.TCP 揮手爲什麼需要四次呢?
再來回顧下四次揮手雙方發 FIN
包的過程,就能理解爲什麼需要四次了。
- 關閉連接時,客戶端向服務端發送
FIN
時,僅僅表示客戶端不再發送數據了但是還能接收數據。 - 服務端收到客戶端的
FIN
報文時,先回一個ACK
應答報文,而服務端可能還有數據需要處理和發送,等服務端不再發送數據時,才發送FIN
報文給客戶端來表示同意現在關閉連接。
從上面過程可知,服務端通常需要等待完成數據的發送和處理,所以服務端的 ACK
和 FIN
一般都會分開發送,從而比三次握手導致多了一次。
32.TCP 四次揮手過程中,爲什麼需要等待 2MSL, 才進入 CLOSED 關閉狀態?
爲什麼需要等待?
1. 爲了保證客戶端發送的最後一個 ACK 報文段能夠到達服務端。 這個 ACK 報文段有可能丟失,因而使處在 LAST-ACK 狀態的服務端就收不到對已發送的 FIN + ACK 報文段的確認。服務端會超時重傳這個 FIN+ACK 報文段,而客戶端就能在 2MSL 時間內(超時 + 1MSL 傳輸)收到這個重傳的 FIN+ACK 報文段。接着客戶端重傳一次確認,重新啓動 2MSL 計時器。最後,客戶端和服務器都正常進入到 CLOSED 狀態。
2. 防止已失效的連接請求報文段出現在本連接中。客戶端在發送完最後一個 ACK 報文段後,再經過時間 2MSL,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣就可以使下一個連接中不會出現這種舊的連接請求報文段。
爲什麼等待的時間是2MSL?
MSL 是 Maximum Segment Lifetime,報⽂最⼤⽣存時間,它是任何報⽂在⽹絡上存在的最⻓時間,超過這個時間報⽂將被丟棄。
TIME_WAIT 等待 2 倍的 MSL,⽐較合理的解釋是: ⽹絡中可能存在來⾃發送⽅的數據包,當這些發送⽅的數據包被接收⽅處理後⼜會向對⽅發送響應,所以⼀來⼀回需要等待 2 倍的時間。
⽐如如果被動關閉⽅沒有收到斷開連接的最後的 ACK 報⽂,就會觸發超時重發 Fin 報⽂,另⼀⽅接收到 FIN 後,會重發 ACK 給被動關閉⽅, ⼀來⼀去正好 2 個 MSL。
33.保活計時器有什麼用?
除時間等待計時器外,TCP 還有一個保活計時器(keepalive timer)。
設想這樣的場景:客戶已主動與服務器建立了 TCP 連接。但後來客戶端的主機突然發生故障。顯然,服務器以後就不能再收到客戶端發來的數據。因此,應當有措施使服務器不要再白白等待下去。這就需要使用保活計時器了。
服務器每收到一次客戶端的數據,就重新設置保活計時器,時間的設置通常是兩個小時。若兩個小時都沒有收到客戶端的數據,服務端就發送一個探測報文段,以後則每隔 75 秒鐘發送一次。若連續發送 10 個探測報文段後仍然無客戶端的響應,服務端就認爲客戶端出了故障,接着就關閉這個連接。
34.CLOSE-WAIT 和 TIME-WAIT 的狀態和意義?
CLOSE-WAIT狀態有什麼意義?
服務端收到客戶端關閉連接的請求並確認之後,就會進入CLOSE-WAIT狀態。此時服務端可能還有一些數據沒有傳輸完成,因此不能立即關閉連接,而CLOSE-WAIT狀態就是爲了保證服務端在關閉連接之前將待發送的數據處理完。
TIME-WAIT有什麼意義?
TIME-WAIT狀態發生在第四次揮手,當客戶端向服務端發送ACK確認報文後進入TIME-WAIT狀態。
它存在的意義主要是兩個:
-
防⽌舊連接的數據包
如果客戶端收到服務端的FIN報文之後立即關閉連接,但是此時服務端對應的端口並沒有關閉,如果客戶端在相同端口建立新的連接,可能會導致新連接收到舊連接殘留的數據包,導致不可預料的異常發生。
-
保證連接正確關閉
假設客戶端最後一次發送的ACK包在傳輸的時候丟失了,由於TCP協議的超時重傳機制,服務端將重發FIN報文,如果客戶端沒有維持TIME-WAIT狀態而直接關閉的話,當收到服務端重新發送的FIN包時,客戶端就會使用RST包來響應服務端,導致服務端以爲有錯誤發生,然而實際關閉連接過程是正常的。
35.TIME_WAIT 狀態過多會導致什麼問題?怎麼解決?
TIME_WAIT 狀態過多會導致什麼問題?
如果服務器有處於 TIME-WAIT 狀態的 TCP,則說明是由服務器⽅主動發起的斷開請求。
過多的 TIME-WAIT 狀態主要的危害有兩種:
第⼀是內存資源佔⽤;
第⼆是對端⼝資源的佔⽤,⼀個 TCP 連接⾄少消耗⼀個本地端⼝;
怎麼解決TIME_WAIT 狀態過多?
- 服務器可以設置SO_REUSEADDR套接字來通知內核,如果端口被佔用,但是TCP連接位於TIME_WAIT 狀態時可以重用端口。
- 還可以使用長連接的方式來減少TCP的連接和斷開,在長連接的業務裏往往不需要考慮TIME_WAIT狀態。
36.說說 TCP 報文首部的格式?
看一下TCP報文首部的格式:
-
16 位端口號:源端口號,主機該報文段是來自哪裏;目標端口號,要傳給哪個上層協議或應用程序
-
32 位序號:一次 TCP 通信(從 TCP 連接建立到斷開)過程中某一個傳輸方向上的字節流的每個字節的編號。
-
32 位確認號:用作對另一方發送的 tcp 報文段的響應。其值是收到的 TCP 報文段的序號值加 1。
-
4 位首部長度:表示 tcp 頭部有多少個 32bit 字(4 字節)。因爲 4 位最大能標識 15,所以 TCP 頭部最長是 60 字節。
-
6 位標誌位:URG(緊急指針是否有效),ACk(表示確認號是否有效),PST(緩衝區尚未填滿),RST(表示要求對方重新建立連接),SYN(建立連接消息標誌接),FIN(表示告知對方本端要關閉連接了)
-
16 位窗口大小:是 TCP 流量控制的一個手段。這裏說的窗口,指的是接收通告窗口。它告訴對方本端的 TCP 接收緩衝區還能容納多少字節的數據,這樣對方就可以控制發送數據的速度。
-
16 位校驗和:由發送端填充,接收端對 TCP 報文段執行 CRC 算法以檢驗 TCP 報文段在傳輸過程中是否損壞。注意,這個校驗不僅包括 TCP 頭部,也包括數據部分。這也是 TCP 可靠傳輸的一個重要保障。
-
16 位緊急指針:一個正的偏移量。它和序號字段的值相加表示最後一個緊急數據的下一字節的序號。因此,確切地說,這個字段是緊急指針相對當前序號的偏移,不妨稱之爲緊急偏移。TCP 的緊急指針是發送端向接收端發送緊急數據的方法。
37.TCP 是如何保證可靠性的?
TCP主要提供了檢驗和、序列號/確認應答、超時重傳、最大消息長度、滑動窗口控制等方法實現了可靠性傳輸。
-
連接管理:TCP使用三次握手和四次揮手保證可靠地建立連接和釋放連接,這裏就不用多說了。
-
校驗和:TCP 將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果接收端的檢驗和有差錯,TCP 將丟棄這個報文段和不確認收到此報文段。
- 序列號/確認應答:TCP 給發送的每一個包進行編號,接收方會對收到的包進行應答,發送方就會知道接收方是否收到對應的包,如果發現沒有收到,就會重發,這樣就能保證數據的完整性。就像老師上課,會問一句,這一章聽懂了嗎?沒聽懂再講一遍。
- 流量控制:TCP 連接的每一方都有固定大小的緩衝空間,TCP的接收端只允許發送端發送接收端緩衝區能接納的數據。當接收方來不及處理髮送方的數據,能提示發送方降低發送的速率,防止包丟失。TCP 使用的流量控制協議是可變大小的滑動窗口協議。 (TCP 利用滑動窗口實現流量控制)
- 最大消息長度:在建立TCP連接的時候,雙方約定一個最大的長度(MSS)作爲發送的單位,重傳的時候也是以這個單位來進行重傳。理想的情況下是該長度的數據剛好不被網絡層分塊。
- 超時重傳:超時重傳是指發送出去的數據包到接收到確認包之間的時間,如果超過了這個時間會被認爲是丟包了,需要重傳。
- 擁塞控制:如果網絡非常擁堵,此時再發送數據就會加重網絡負擔,那麼發送的數據段很可能超過了最大生存時間也沒有到達接收方,就會產生丟包問題。爲此TCP引入慢啓動機制,先發出少量數據,就像探路一樣,先摸清當前的網絡擁堵狀態後,再決定按照多大的速度傳送數據。
38.說說 TCP 的流量控制?
TCP 提供了一種機制,可以讓發送端根據接收端的實際接收能力控制發送的數據量,這就是流量控制。
TCP 通過滑動窗口來控制流量,我們看下簡要流程:
- 首先雙方三次握手,初始化各自的窗口大小,均爲 400 個字節。
- 假如當前發送方給接收方發送了 200 個字節,那麼,發送方的
SND.NXT
會右移 200 個字節,也就是說當前的可用窗口減少了 200 個字節。 - 接受方收到後,放到緩衝隊列裏面,REV.WND =400-200=200 字節,所以 win=200 字節返回給發送方。接收方會在 ACK 的報文首部帶上縮小後的滑動窗口 200 字節
- 發送方又發送 200 字節過來,200 字節到達,繼續放到緩衝隊列。不過這時候,由於大量負載的原因,接受方處理不了這麼多字節,只能處理 100 字節,剩餘的 100 字節繼續放到緩衝隊列。這時候,REV.WND = 400-200-100=100 字節,即 win=100 返回發送方。
- 發送方繼續發送 100 字節過來,這時候,接收窗口 win 變爲 0。
- 發送方停止發送,開啓一個定時任務,每隔一段時間,就去詢問接受方,直到 win 大於 0,才繼續開始發送。
39.詳細說說 TCP 的滑動窗口?
TCP 發送一個數據,如果需要收到確認應答,纔會發送下一個數據。這樣的話就會有個缺點:效率會比較低。
“用一個比喻,我們在微信上聊天,你打完一句話,我回復一句之後,你才能打下一句。假如我沒有及時回覆呢?你是把話憋着不說嗎?然後傻傻等到我回復之後再接着發下一句?”
爲了解決這個問題,TCP 引入了窗口,它是操作系統開闢的一個緩存空間。窗口大小值表示無需等待確認應答,而可以繼續發送數據的最大值。
TCP 頭部有個字段叫 win,也即那個 16 位的窗口大小,它告訴對方本端的 TCP 接收緩衝區還能容納多少字節的數據,這樣對方就可以控制發送數據的速度,從而達到流量控制的目的。
“通俗點講,就是接受方每次收到數據包,在發送確認報文的時候,同時告訴發送方,自己的緩存區還有多少空餘空間,緩衝區的空餘空間,我們就稱之爲接受窗口大小。這就是 win。”
TCP 滑動窗口分爲兩種: 發送窗口和接收窗口。發送端的滑動窗口包含四大部分,如下:
- 已發送且已收到 ACK 確認
- 已發送但未收到 ACK 確認
- 未發送但可以發送
- 未發送也不可以發送
-
深藍色框裏就是發送窗口。
-
SND.WND: 表示發送窗口的大小, 上圖虛線框的格子數是 10個,即發送窗口大小是 10。
-
SND.NXT:下一個發送的位置,它指向未發送但可以發送的第一個字節的序列號。
-
SND.UNA: 一個絕對指針,它指向的是已發送但未確認的第一個字節的序列號。
接收方的滑動窗口包含三大部分,如下:
- 已成功接收並確認
- 未收到數據但可以接收
- 未收到數據並不可以接收的數據
- 藍色框內,就是接收窗口。
- REV.WND: 表示接收窗口的大小, 上圖虛線框的格子就是 9 個。
- REV.NXT: 下一個接收的位置,它指向未收到但可以接收的第一個字節的序列號。
40.瞭解Nagle 算法和延遲確認嗎?
Nagle 算法和延遲確認是幹什麼的?
當我們 TCP 報⽂的承載的數據⾮常⼩的時候,例如⼏個字節,那麼整個⽹絡的效率是很低的,因爲每個 TCP 報⽂中都會有 20 個字節的 TCP 頭部,也會有 20 個字節的 IP 頭部,⽽數據只有⼏個字節,所以在整個報⽂中有效數據佔有的比例就會⾮常低。
這就好像快遞員開着⼤貨⻋送⼀個⼩包裹⼀樣浪費。
那麼就出現了常⻅的兩種策略,來減少⼩報⽂的傳輸,分別是:
- Nagle 算法
- 延遲確認
Nagle 算法
Nagle 算法:任意時刻,最多隻能有一個未被確認的小段。所謂 “小段”,指的是小於 MSS 尺寸的數據塊,所謂 “未被確認”,是指一個數據塊發送出去後,沒有收到對方發送的 ACK 確認該數據已收到。
Nagle 算法的策略:
- 沒有已發送未確認報⽂時,⽴刻發送數據。
- 存在未確認報⽂時,直到「沒有已發送未確認報⽂」或「數據⻓度達到 MSS ⼤⼩」時,再發送數據。
只要沒滿⾜上⾯條件中的⼀條,發送⽅⼀直在囤積數據,直到滿⾜上⾯的發送條件。
延遲確認
事實上當沒有攜帶數據的 ACK,它的⽹絡效率也是很低的,因爲它也有 40 個字節的 IP 頭 和 TCP 頭,但卻沒有攜帶數據報⽂。
爲了解決 ACK 傳輸效率低問題,所以就衍⽣出了 TCP 延遲確認。
TCP 延遲確認的策略:
-
當有響應數據要發送時,ACK 會隨着響應數據⼀起⽴刻發送給對⽅
-
當沒有響應數據要發送時,ACK 將會延遲⼀段時間,以等待是否有響應數據可以⼀起發送
-
如果在延遲等待發送 ACK 期間,對⽅的第⼆個數據報⽂⼜到達了,這時就會⽴刻發送 ACK
一般情況下,Nagle 算法和延遲確認不能一起使用,Nagle 算法意味着延遲發,延遲確認意味着延遲接收,兩個湊在一起就會造成更大的延遲,會產生性能問題。
41.說說TCP 的擁塞控制?
什麼是擁塞控制?不是有了流量控制嗎?
前⾯的流量控制是避免發送⽅的數據填滿接收⽅的緩存,但是並不知道整個⽹絡之中發⽣了什麼。
⼀般來說,計算機⽹絡都處在⼀個共享的環境。因此也有可能會因爲其他主機之間的通信使得⽹絡擁堵。
在⽹絡出現擁堵時,如果繼續發送⼤量數據包,可能會導致數據包時延、丟失等,這時 TCP 就會重傳數據,但是⼀重傳就會導致⽹絡的負擔更重,於是會導致更⼤的延遲以及更多的丟包,這個情況就會進⼊惡性循環被不斷地放⼤....
所以,TCP 不能忽略整個網絡中發⽣的事,它被設計成⼀個⽆私的協議,當⽹絡發送擁塞時,TCP 會⾃我犧牲,降低發送的數據流。
於是,就有了擁塞控制,控制的⽬的就是避免發送⽅的數據填滿整個⽹絡。
就像是一個水管,不能讓太多的水(數據流)流入水管,如果超過水管的承受能力,水管會被撐爆(丟包)。
發送方維護一個擁塞窗口 cwnd(congestion window) 的變量,調節所要發送數據的量。
什麼是擁塞窗⼝?和發送窗⼝有什麼關係呢?
擁塞窗⼝ cwnd是發送⽅維護的⼀個的狀態變量,它會根據⽹絡的擁塞程度動態變化的。
發送窗⼝ swnd 和接收窗⼝ rwnd 是約等於的關係,那麼由於加⼊了擁塞窗⼝的概念後,此時發送窗⼝的值是swnd = min(cwnd, rwnd),也就是擁塞窗⼝和接收窗⼝中的最⼩值。
擁塞窗⼝ cwnd 變化的規則:
- 只要⽹絡中沒有出現擁塞, cwnd 就會增⼤;
- 但⽹絡中出現了擁塞, cwnd 就減少;
擁塞控制有哪些常用算法?
擁塞控制主要有這幾種常用算法:
-
慢啓動
-
擁塞避免
-
擁塞發生
-
快速恢復
慢啓動算法
慢啓動算法,慢慢啓動。
它表示 TCP 建立連接完成後,一開始不要發送大量的數據,而是先探測一下網絡的擁塞程度。由小到大逐漸增加擁塞窗口的大小,如果沒有出現丟包,每收到一個 ACK,就將擁塞窗口 cwnd 大小就加 1(單位是 MSS)。每輪次發送窗口增加一倍,呈指數增長,如果出現丟包,擁塞窗口就減半,進入擁塞避免階段。
舉個例子:
- 連接建⽴完成後,⼀開始初始化 cwnd = 1 ,表示可以傳⼀個 MSS ⼤⼩的數據。
- 當收到⼀個 ACK 確認應答後,cwnd 增加 1,於是⼀次能夠發送 2 個
- 當收到 2 個的 ACK 確認應答後, cwnd 增加 2,於是就可以⽐之前多發2 個,所以這⼀次能夠發送 4 個
- 當這 4 個的 ACK 確認到來的時候,每個確認 cwnd 增加 1, 4 個確認 cwnd 增加 4,於是就可以⽐之前多發4 個,所以這⼀次能夠發送 8 個。
發包的個數是指數性的增⻓。
爲了防止 cwnd 增長過大引起網絡擁塞,還需設置一個慢啓動閥值 ssthresh(slow start threshold)狀態變量。當cwnd
到達該閥值後,就好像水管被關小了水龍頭一樣,減少擁塞狀態。即當 cwnd >ssthresh 時,進入了擁塞避免算法。
擁塞避免算法
一般來說,慢啓動閥值 ssthresh 是 65535 字節,cwnd
到達慢啓動閥值後
-
每收到一個 ACK 時,cwnd = cwnd + 1/cwnd
-
當每過一個 RTT 時,cwnd = cwnd + 1
顯然這是一個線性上升的算法,避免過快導致網絡擁塞問題。
接着上面慢啓動的例子,假定 ssthresh 爲 8 : :
- 當 8 個 ACK 應答確認到來時,每個確認增加 1/8,8 個 ACK 確認 cwnd ⼀共增加 1,於是這⼀次能夠發送 9個 MSS ⼤⼩的數據,變成了線性增⻓。
擁塞發生
當網絡擁塞發生丟包時,會有兩種情況:
-
RTO 超時重傳
-
快速重傳
如果是發生了 RTO 超時重傳,就會使用擁塞發生算法
- 慢啓動閥值 sshthresh = cwnd /2
- cwnd 重置爲 1
- 進入新的慢啓動過程
這種方式就像是飆車的時候急剎車,還飛速倒車,這。。。
其實還有更好的處理方式,就是快速重傳。發送方收到 3 個連續重複的 ACK 時,就會快速地重傳,不必等待 RTO 超時再重傳。
發⽣快速重傳的擁塞發⽣算法:
-
擁塞窗口大小 cwnd = cwnd/2
-
慢啓動閥值 ssthresh = cwnd
-
進入快速恢復算法
快速恢復
快速重傳和快速恢復算法一般同時使用。快速恢復算法認爲,還有 3 個重複 ACK 收到,說明網絡也沒那麼糟糕,所以沒有必要像 RTO 超時那麼強烈。
正如前面所說,進入快速恢復之前,cwnd 和 sshthresh 已被更新:
- cwnd = cwnd /2
- sshthresh = cwnd
然後,進⼊快速恢復算法如下:
- cwnd = sshthresh + 3
- 重傳重複的那幾個 ACK(即丟失的那幾個數據包)
- 如果再收到重複的 ACK,那麼 cwnd = cwnd +1
- 如果收到新數據的 ACK 後, cwnd = sshthresh。因爲收到新數據的 ACK,表明恢復過程已經結束,可以再次進入了擁塞避免的算法了。
42.說說 TCP 的重傳機制?
重傳包括超時重傳、快速重傳、帶選擇確認的重傳(SACK)、重複 SACK 四種。
超時重傳
超時重傳,是 TCP 協議保證數據可靠性的另一個重要機制,其原理是在發送某一個數據以後就開啓一個計時器,在一定時間內如果沒有得到發送的數據報的 ACK 報文,那麼就重新發送數據,直到發送成功爲止。
超時時間應該設置爲多少呢?
先來看下什麼叫 RTT(Round-Trip Time,往返時間)。
RTT 就是數據完全發送完,到收到確認信號的時間,即數據包的一次往返時間。
超時重傳時間,就是 RTO(Retransmission Timeout)。那麼,RTO 到底設置多大呢?
-
如果 RTO 設置很大,等了很久都沒重發,這樣肯定就不行。
-
如果 RTO 設置很小,那很可能數據都沒有丟失,就開始重發了,這會導致網絡阻塞,從而惡性循環,導致更多的超時出現。
一般來說,RTO 略微大於 RTT,效果是最佳的。
其實,RTO 有個標準方法的計算公式,也叫 Jacobson / Karels 算法。
- 首先計算 SRTT(即計算平滑的 RTT)
SRTT = (1 - α) * SRTT + α * RTT //求 SRTT 的加權平均
- 其次,計算 RTTVAR (round-trip time variation)
RTTVAR = (1 - β) * RTTVAR + β * (|RTT - SRTT|) //計算 SRTT 與真實值的差距
- 最後,得出最終的 RTO
RTO = µ * SRTT + ∂ * RTTVAR = SRTT + 4·RTTVAR
在 Linux 下,α = 0.125,β = 0.25, μ = 1,∂ = 4。別問這些參數是怎麼來的,它們是大量實踐,調出的最優參數。
超時重傳不是十分完美的重傳方案,它有這些缺點:
- 當一個報文丟失時,會等待一定的超時週期,才重傳分組,增加了端到端的時延。
- 當一個報文丟失時,在其等待超時的過程中,可能會出現這種情況:其後的報文段已經被接收端接收但卻遲遲得不到確認,發送端會認爲也丟失了,從而引起不必要的重傳,既浪費資源也浪費時間。
並且,對於 TCP,如果發生一次超時重傳,時間間隔下次就會加倍。
快速重傳
TCP 還有另外⼀種快速重傳(Fast Retransmit)機制,它不以時間爲驅動,⽽是以數據驅動重傳。
它不以時間驅動,而是以數據驅動。它是基於接收端的反饋信息來引發重傳的。
可以用它來解決超時重發的時間等待問題,快速重傳流程如下:
在上圖,發送⽅發出了 1,2,3,4,5 份數據:
-
第⼀份 Seq1 先送到了,於是就 Ack 回 2;
-
結果 Seq2 因爲某些原因沒收到,Seq3 到達了,於是還是 Ack 回 2;
-
後⾯的 Seq4 和 Seq5 都到了,但還是 Ack 回 2,因爲 Seq2 還是沒有收到;
-
發送端收到了三個 Ack = 2 的確認,知道了 Seq2 還沒有收到,就會在定時器過期之前,重傳丟失的 Seq2。
-
最後,收到了 Seq2,此時因爲 Seq3,Seq4,Seq5 都收到了,於是 Ack 回 6 。
快速重傳機制只解決了⼀個問題,就是超時時間的問題,但是它依然⾯臨着另外⼀個問題。就是重傳的時候,是重傳之前的⼀個,還是重傳所有的問題。
⽐如對於上⾯的例⼦,是重傳 Seq2 呢?還是重傳 Seq2、Seq3、Seq4、Seq5 呢?因爲發送端並不清楚這連續的三個 Ack 2 是誰傳回來的。
根據 TCP 不同的實現,以上兩種情況都是有可能的。可⻅,這是⼀把雙刃劍。
爲了解決不知道該重傳哪些 TCP 報⽂,於是就有 SACK ⽅法。
帶選擇確認的重傳(SACK)
爲了解決應該重傳多少個包的問題? TCP 提供了帶選擇確認的重傳(即 SACK,Selective Acknowledgment)。
SACK 機制就是,在快速重傳的基礎上,接收方返回最近收到報文段的序列號範圍,這樣發送方就知道接收方哪些數據包是沒收到的。這樣就很清楚應該重傳哪些數據包。
如上圖中,發送⽅收到了三次同樣的 ACK 確認報⽂,於是就會觸發快速重發機制,通過 SACK 信息發現只有200~299 這段數據丟失,則重發時,就只選擇了這個 TCP 段進⾏重發。
重複 SACK(D-SACK)
D-SACK,英文是 Duplicate SACK,是在 SACK 的基礎上做了一些擴展,主要用來告訴發送方,有哪些數據包,自己重複接受了。
DSACK 的目的是幫助發送方判斷,是否發生了包失序、ACK 丟失、包重複或僞重傳。讓 TCP 可以更好的做網絡流控。
例如ACK丟包導致的數據包重複:
- 接收⽅發給發送⽅的兩個 ACK 確認應答都丟失了,所以發送⽅超時後,重傳第⼀個數據包(3000 ~
3499)
- 於是接收⽅發現數據是重複收到的,於是回了⼀個 SACK = 3000~3500,告訴「發送⽅」 3000~3500的數據早已被接收了,因爲 ACK 都到了 4000 了,已經意味着 4000 之前的所有數據都已收到,所以這個SACK 就代表着 D-SACK 。這樣發送⽅就知道了,數據沒有丟,是接收⽅的 ACK 確認報⽂丟了。
43.說說TCP 的粘包和拆包?
TCP 的粘包和拆包更多的是業務上的概念!
什麼是TCP粘包和拆包?
TCP 是面向流,沒有界限的一串數據。TCP 底層並不瞭解上層業務數據的具體含義,它會根據 TCP 緩衝區的實際情況進行包的劃分,所以在業務上認爲,一個完整的包可能會被 TCP 拆分成多個包進行發送,也有可能把多個小的包封裝成一個大的數據包發送,這就是所謂的 TCP 粘包和拆包問題。
爲什麼會產生粘包和拆包呢?
-
要發送的數據小於 TCP 發送緩衝區的大小,TCP 將多次寫入緩衝區的數據一次發送出去,將會發生粘包;
-
接收數據端的應用層沒有及時讀取接收緩衝區中的數據,將發生粘包;
-
要發送的數據大於 TCP 發送緩衝區剩餘空間大小,將會發生拆包;
-
待發送數據大於 MSS(最大報文長度),TCP 在傳輸前將進行拆包。即 TCP 報文長度 - TCP 頭部長度 > MSS。
那怎麼解決呢?
- 發送端將每個數據包封裝爲固定長度
- 在數據尾部增加特殊字符進行分割
- 將數據分爲兩部分,一部分是頭部,一部分是內容體;其中頭部結構大小固定,且有一個字段聲明內容體的大小。
UDP
UDP問的不多,基本上是被拿來和TCP比較。
44.說說 TCP 和 UDP 的區別?
最根本區別:TCP 是面向連接,而 UDP 是無連接。
可以這麼形容:TCP是打電話,UDP是大喇叭。
說說TCP和UDP的應用場景?
- TCP應用場景: 效率要求相對低,但對準確性要求相對高的場景。因爲傳輸中需要對數據確認、重發、排序等操作,相比之下效率沒有UDP高。例如:文件傳輸(準確高要求高、但是速度可以相對慢)、收發郵件、遠程登錄。
- UDP應用場景: 效率要求相對高,對準確性要求相對低的場景。例如:QQ聊天、在線視頻、網絡語音電話(即時通訊,速度要求高,但是出現偶爾斷續不是太大問題,並且此處完全不可以使用重發機制)、廣播通信(廣播、多播)。
45.爲什麼QQ採用UDP協議?
PS:這是多年前的老題了,拉出來懷懷舊。
- 首先,QQ並不是完全基於UDP實現。比如在使用QQ進行文件傳輸等活動的時候,就會使用TCP作爲可靠傳輸的保證。
- 使用UDP進行交互通信的好處在於,延遲較短,對數據丟失的處理比較簡單。同時,TCP是一個全雙工協議,需要建立連接,所以網絡開銷也會相對大。
- 如果使用QQ語音和QQ視頻的話,UDP的優勢就更爲突出了,首先延遲較小。最重要的一點是不可靠傳輸,這意味着如果數據丟失的話,不會有重傳。因爲用戶一般來說可以接受圖像稍微模糊一點,聲音稍微不清晰一點,但是如果在幾秒鐘以後再出現之前丟失的畫面和聲音,這恐怕是很難接受的。
- 由於QQ的服務器設計容量是海量級的應用,一臺服務器要同時容納十幾萬的併發連接,因此服務器端只有採用UDP協議與客戶端進行通訊才能保證這種超大規模的服務
簡單總結一下:UDP協議是無連接方式的協議,它的效率高,速度快,佔資源少,對服務器的壓力比較小。但是其傳輸機制爲不可靠傳送,必須依靠輔助的算法來完成傳輸控制。QQ採用的通信協議以UDP爲主,輔以TCP協議。
46.UDP協議爲什麼不可靠?
UDP在傳輸數據之前不需要先建立連接,遠地主機的運輸層在接收到UDP報文後,不需要確認,提供不可靠交付。總結就以下四點:
- 不保證消息交付:不確認,不重傳,無超時
- 不保證交付順序:不設置包序號,不重排,不會發生隊首阻塞
- 不跟蹤連接狀態:不必建立連接或重啓狀態機
- 不進行擁塞控制:不內置客戶端或網絡反饋機制
47.DNS爲什麼要用UDP?
更準確地說,DNS既使用TCP又使用UDP。
當進行區域傳送(主域名服務器向輔助域名服務器傳送變化的那部分數據)時會使用TCP,因爲數據同步傳送的數據量比一個請求和應答的數據量要多,而TCP允許的報文長度更長,因此爲了保證數據的正確性,會使用基於可靠連接的TCP。
當客戶端想DNS服務器查詢域名(域名解析)的時候,一般返回的內容不會超過UDP報文的最大長度,即512字節,用UDP傳輸時,不需要創建連接,從而大大提高了響應速度,但這要求域名解析服務器和域名服務器都必須自己處理超時和重傳從而保證可靠性。
IP
48.IP 協議的定義和作用?
IP協議是什麼?
IP協議(Internet Protocol)又被稱爲互聯網協議,是支持網間互聯的數據包協議,工作在網際層,主要目的就是爲了提高網絡的可擴展性。
通過網際協議IP,可以把參與互聯的,性能各異的網絡看作一個統一的網絡。
和傳輸層TCP相比,IP協議是一種無連接/不可靠、盡力而爲的數據包傳輸服務,和TCP協議一起構成了TCP/IP協議的核心。
IP協議有哪些作用?
IP協議主要有以下幾個作用:
- 尋址和路由:在IP數據報中攜帶源IP地址和目的IP地址來表示該數據包的源主機和目標主機。IP數據報在傳輸過程中,每個中間節點(IP網關、路由器)只根據網絡地址來進行轉發,如果中間節點是路由器,則路由器會根據路由表選擇合適的路徑。IP協議根據路由選擇協議提供的路由信息對IP數據報進行轉發,直至目標主機。
- 分段和重組:IP數據報在傳輸過程中可能會經過不同的網絡,在不同的網絡中數據報的最大長度限制是不同的,IP協議通過給每個IP數據報分配一個標識符以及分段與組裝的相關信息,使得數據報在不同的網絡中能夠被傳輸,被分段後的IP數據報可以獨立地在網絡中進行轉發,在達到目標主機後由目標主機完成重組工作,恢復出原來的IP數據報。
傳輸層協議和網絡層協議有什麼區別?
網絡層協議負責提供主機間的邏輯通信;傳輸層協議負責提供進程間的邏輯通信。
49.IP 地址有哪些分類?
一個IP地址在這鞥個互聯網範圍內是惟一的,一般可以這麼認爲,IP 地址 = {<網絡號>,<主機號>}。
-
網絡號:它標誌主機所連接的網絡地址表示屬於互聯網的哪一個網絡。
-
主機號:它標誌主機地址表示其屬於該網絡中的哪一臺主機。
IP 地址分爲 A,B,C,D,E 五大類:
-
A 類地址 (1~126):以 0 開頭,網絡號佔前 8 位,主機號佔後面 24 位。
-
B 類地址 (128~191):以 10 開頭,網絡號佔前 16 位,主機號佔後面 16 位。
-
C 類地址 (192~223):以 110 開頭,網絡號佔前 24 位,主機號佔後面 8 位。
-
D 類地址 (224~239):以 1110 開頭,保留爲多播地址。
-
E 類地址 (240~255):以 1111開頭,保留位爲將來使用
50.域名和 IP 的關係?一個 IP 可以對應多個域名嗎?
- IP地址在同一個網絡中是惟一的,用來標識每一個網絡上的設備,其相當於一個人的身份證號
- 域名在同一個網絡中也是惟一的,就像是一個人的名字、綽號
假如你有多個不用的綽號,你的朋友可以用其中任何一個綽號叫你,但你的身份證號碼卻是惟一的。但同時你的綽號也可能和別人重複,假如你不在,有人叫你的綽號,其它人可能就答應了。
一個域名可以對應多個IP,但這種情況DNS做負載均衡的,在用戶訪問過程中,一個域名只能對應一個IP。
而一個IP卻可以對應多個域名,是一對多的關係。
51.IPV4 地址不夠如何解決?
我們知道,IP地址有32位,可以標記2的32次方個地址,聽起來很多,但是全球的網絡設備數量已經遠遠超過這個數字,所以IPV4地址已經不夠用了,那怎麼解決呢?
- DHCP:動態主機配置協議,動態分配IP地址,只給接入網絡的設備分配IP地址,因此同一個MAC地址的設備,每次接入互聯網時,得到的IP地址不一定是相同的,該協議使得空閒的IP地址可以得到充分利用。
- CIDR:無類別域間路由。CIDR消除了傳統的A類、B類、C類地址以及劃分子網的概念,因而更加有效地分配IPv4的地址空間,但無法從根本上解決地址耗盡的問題。
- NAT:網絡地址轉換協議,我們知道屬於不同局域網的主機可以使用相同的IP地址,從而一定程度上緩解了IP資源枯竭的問題,然而主機在局域網中使用的IP地址是不能在公網中使用的,當局域網主機想要與公網主機進行通信時,NAT方法可以將該主機IP地址轉換爲全球IP地址。該協議能夠有效解決IP地址不足的問題。
- IPv6:作爲接替IPv4的下一代互聯網協議,其可以實現2的128次方個地址,而這個數量級,即使給地球上每一粒沙子都分配一個IP地址也夠用,該協議能夠從根本上解決IPv4地址不夠用的問題。
52.說下 ARP 協議的工作過程?
ARP 協議,Address Resolution Protocol,地址解析協議,它是用於實現 IP 地址到 MAC 地址的映射。
-
首先,每臺主機都會在自己的 ARP 緩衝區中建立一個 ARP 列表,以表示 IP 地址和 MAC 地址的對應關係。
-
當源主機需要將一個數據包要發送到目的主機時,會首先檢查自己的 ARP 列表,是否存在該 IP 地址對應的 MAC 地址;如果有﹐就直接將數據包發送到這個 MAC 地址;如果沒有,就向本地網段發起一個 ARP 請求的廣播包,查詢此目的主機對應的 MAC 地址。此 ARP 請求的數據包裏,包括源主機的 IP 地址、硬件地址、以及目的主機的 IP 地址。
-
網絡中所有的主機收到這個 ARP 請求後,會檢查數據包中的目的 IP 是否和自己的 IP 地址一致。如果不相同,就會忽略此數據包;如果相同,該主機首先將發送端的 MAC 地址和 IP 地址添加到自己的 ARP 列表中,如果 ARP 表中已經存在該 IP 的信息,則將其覆蓋,然後給源主機發送一個 ARP 響應數據包,告訴對方自己是它需要查找的 MAC 地址。
-
源主機收到這個 ARP 響應數據包後,將得到的目的主機的 IP 地址和 MAC 地址添加到自己的 ARP 列表中,並利用此信息開始數據的傳輸。如果源主機一直沒有收到 ARP 響應數據包,表示 ARP 查詢失敗。
53.爲什麼既有IP地址,又有MAC 地址?
MAC地址和IP地址都有什麼作用?
- MAC地址是數據鏈路層和物理層使用的地址,是寫在網卡上的物理地址,用來定義網絡設備的位置,不可變更。
- IP地址是網絡層和以上各層使用的地址,是一種邏輯地址。IP地址用來區別網絡上的計算機。
爲什麼有了MAC地址還需要IP地址?
如果我們只使用MAC地址進行尋址的話,我們需要路由器記住每個MAC地址屬於哪個子網,不然一次路由器收到數據包都要滿世界尋找目的MAC地址。而我們知道MAC地址的長度爲48位,也就是最多共有2的48次方個MAC地址,這就意味着每個路由器需要256T的內存,顯然是不現實的。
和MAC地址不同,IP地址是和地域相關的,在一個子網中的設備,我們給其分配的IP地址前綴都是一樣的,這樣路由器就能根據IP地址的前綴知道這個設備屬於哪個子網,剩下的尋址就交給子網內部實現,從而大大減少了路由器所需要的內存。
爲什麼有了IP地址還需要MAC地址?
-
只有當設備連入網絡時,才能根據他進入了哪個子網來爲其分配IP地址,在設備還沒有IP地址的時候,或者在分配IP的過程中。我們需要MAC地址來區分不同的設備。
-
IP 地址可以比作爲地址,MAC 地址爲收件人,在一次通信過程中,兩者是缺一不可的。
54.ICMP 協議的功能?
ICMP(Internet Control Message Protocol) ,網際控制報文協議。
-
ICMP 協議是一種面向無連接的協議,用於傳輸出錯報告控制信息。
-
它是一個非常重要的協議,它對於網絡安全具有極其重要的意義。它屬於網絡層協議,主要用於在主機與路由器之間傳遞控制信息,包括報告錯誤、交換受限控制和狀態信息等。
-
當遇到 IP 數據無法訪問目標、IP 路由器無法按當前的傳輸速率轉發數據包等情況時,會自動發送 ICMP 消息。
比如我們日常使用得比較多的 ping,就是基於 ICMP 的。
55.說下 ping 的原理?
ping,Packet Internet Groper,是一種因特網包探索器,用於測試網絡連接量的程序。Ping 是工作在 TCP/IP 網絡體系結構中應用層的一個服務命令, 主要是向特定的目的主機發送 ICMP(Internet Control Message Protocol 因特網報文控制協議) 請求報文,測試目的站是否可達及瞭解其有關狀態。
一般來說,ping 可以用來檢測網絡通不通。它是基於ICMP
協議工作的。假設機器 A ping 機器 B,工作過程如下:
- ping 通知系統,新建一個固定格式的 ICMP 請求數據包
- ICMP 協議,將該數據包和目標機器 B 的 IP 地址打包,一起轉交給 IP 協議層
- IP 層協議將本機 IP 地址爲源地址,機器 B 的 IP 地址爲目標地址,加上一些其他的控制信息,構建一個 IP 數據包
- 先獲取目標機器 B 的 MAC 地址。
- 數據鏈路層構建一個數據幀,目的地址是 IP 層傳過來的 MAC 地址,源地址是本機的 MAC 地址
- 機器 B 收到後,對比目標地址,和自己本機的 MAC 地址是否一致,符合就處理返回,不符合就丟棄。
- 根據目的主機返回的 ICMP 回送回答報文中的時間戳,從而計算出往返時間
- 最終顯示結果有這幾項:發送到目的主機的 IP 地址、發送 & 收到 & 丟失的分組數、往返時間的最小、最大 & 平均值
網絡安全
56.說說有哪些安全攻擊?
網絡安全攻擊主要分爲兩種類型,被動攻擊和主動攻擊:
- 被動攻擊:是指攻擊者從網絡上竊聽他人的通信內容,通常把這類攻擊稱爲截獲,被動攻擊主要有兩種形式:消息內容泄露攻擊和流量分析攻擊。由於攻擊者沒有修改數據,使得這種攻擊很難被檢測到。
- 主動攻擊:直接對現有的數據和服務造成影響,常見的主動攻擊類型有:
- 篡改:攻擊者故意篡改網絡上送的報文,甚至把完全僞造的報文傳送給接收方。
- 惡意程序:惡意程序種類繁多,包括計算機病毒、計算機蠕蟲、特洛伊木馬、後門入侵、流氓軟件等等。
- 拒絕服務Dos:攻擊者向服務器不停地發送分組,使服務器無法提供正常服務。
57.DNS劫持瞭解嗎?
DNS劫持即域名劫持,是通過將原域名對應的IP地址進行替換,從而使用戶訪問到錯誤的網站,或者使用戶無法正常訪問網站的一種攻擊方式。
域名劫持往往只能在特定的網絡範圍內進行,範圍外的DNS服務器能夠返回正常的IP地址。攻擊者可以冒充原域名所屬機構,通過電子郵件的方式修改組織機構的域名註冊信息,或者將域名轉讓給其它主持,並將新的域名信息保存在所指定的DNS服務器中,從而使用戶無法對原域名來進行解析以訪問目標地址。
DNS劫持的步驟是什麼樣的?
- 獲取要劫持的域名信息:攻擊者會首先訪問域名查詢要劫持的站點的域名信息。
- 控制域名響應的E-Mail賬號:在獲取到域名信息後,攻擊者通過暴力破解或者專門的方法破解公司註冊域名時使用的E-mail賬號所對應的密碼,更高級的攻擊者甚至能夠直接對E-Mail進行信息竊取。
- 修改註冊信息:當攻擊者破解了E-Mail後,會利用相關的更改功能修改該域名的註冊信息,包括域名擁有者信息,DNS服務器信息等。
- 使用E-Mail收發確認函:在修改完註冊信息後,攻擊者E-Mail在真正擁有者之前收到修改域名註冊信息的相關確認信息,並回復確認修改文件,待網絡公司恢復已成功修改信件後,攻擊者便成功完成DNS劫持。
怎麼應對DNS劫持?
- 直接通過IP地址訪問網站,避開DNS劫持
- 由於域名劫持往往只能在特定的網絡範圍內進行,因此一些高級用戶可以通過網絡設置讓DNS指向正常的域名服務器以實現對目標網址的正常訪問,例如計算機首選DNS服務器的地址固定爲8.8.8.8。
58.什麼是 CSRF 攻擊?如何避免?
什麼是 CSRF 攻擊?
CSRF,跨站請求僞造(英文全稱是 Cross-site request forgery),是一種挾持用戶在當前已登錄的 Web 應用程序上執行非本意的操作的攻擊方法。
CSRF 是如何攻擊的呢?
來看一個例子:
-
用戶登陸銀行,沒有退出,瀏覽器包含了 用戶 在銀行的身份認證信息。
-
攻擊者將僞造的轉賬請求,包含在在帖子
-
用戶在銀行網站保持登陸的情況下,瀏覽帖子
-
將僞造的轉賬請求連同身份認證信息,發送到銀行網站
-
銀行網站看到身份認證信息,以爲就是 用戶的合法操作,最後造成用戶資金損失。
怎麼應對 CSRF 攻擊呢?
-
檢查 Referer 字段
HTTP頭中的Referer字段記錄了該 HTTP 請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求來自於同一個網站,而如果黑客要對其實施 CSRF攻擊,他一般只能在他自己的網站構造請求。因此,可以通過驗證Referer值來防禦CSRF 攻擊。
-
添加校驗 token
以在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端建立一個攔截器來驗證這個 token,如果請求中沒有token或者 token 內容不正確,則認爲可能是 CSRF 攻擊而拒絕該請求。
-
敏感操作多重校驗
對一些敏感的操作,除了需要校驗用戶的認證信息,還可以通過郵箱確認、驗證碼確認這樣的方式多重校驗。
59.什麼是 DoS、DDoS、DRDoS 攻擊?
-
DOS: (Denial of Service), 翻譯過來就是拒絕服務, 一切能引起拒絕 行爲的攻擊都被稱爲 DOS 攻擊。最常見的 DoS 攻擊就有計算機網絡寬帶攻擊、連通性攻擊。
-
DDoS: (Distributed Denial of Service),翻譯過來是分佈式拒絕服務。是指處於不同位置的多個攻擊者同時向一個或幾個目標發動攻擊,或者一個攻擊者控制了位於不同位置的多臺機器,並利用這些機器對受害者同時實施攻擊。
主要形式有流量攻擊和資源耗盡攻擊,常見的 DDoS攻擊有: SYN Flood、Ping of Death、ACK Flood、UDP Flood 等。
-
DRDoS: (Distributed Reflection Denial of Service),中文是分佈式反射拒絕服務,該方式靠的是發送大量帶有被害者 IP 地址的數據包給攻擊主機,然後攻擊主機對 IP 地址源做出大量回應,從而形成拒絕服務攻擊。
如何防範DDoS?
針對DDoS中的流量攻擊,最直接的方法是增加帶寬,理論上只要帶寬大於攻擊流量就可以了,但是這種方法成本非常高。在有充足帶寬的前提下,我們應該儘量提升路由器、網卡、交換機等硬件設施的配置。
針對資源耗盡攻擊,我們可以升級主機服務器硬件,在網絡帶寬得到保證的前提下,使得服務器能夠有效對抗海量的SYN攻擊包。我們也可以安裝專業的抗DDoS防火牆,從而對抗SYN Flood等流量型攻擊。瓷碗,負載均衡,CDN等技術都能有效對抗DDos攻擊。
60.什麼是 XSS 攻擊,如何避免?
XSS 攻擊也是比較常見,XSS,叫跨站腳本攻擊(Cross-Site Scripting),因爲會與層疊樣式表 (Cascading Style Sheets, CSS) 的縮寫混淆,因此有人將跨站腳本攻擊縮寫爲 XSS。它指的是惡意攻擊者往 Web 頁面裏插入惡意 html 代碼,當用戶瀏覽網頁的時候,嵌入其中 Web 裏面的 html 代碼會被執行,從而達到惡意攻擊用戶的特殊目的。
XSS 攻擊一般分三種類型:存儲型 、反射型 、DOM 型 XSS
XSS 是如何攻擊的呢?
簡單說,XSS的攻擊方式就是想辦法“教唆”用戶的瀏覽器去執行一些這個網頁中原本不存在的前端代碼。
拿反射型舉個例子吧,流程圖如下:
- 攻擊者構造出特殊的 URL,其中包含惡意代碼。
- 用戶打開帶有惡意代碼的 URL 時,訪問正常網站服務器
- 網站服務端將惡意代碼從 URL 中取出,拼接在 HTML 中返回給瀏覽器。
- 用戶瀏覽器接收到響應後解析執行,混在其中的惡意代碼也被執行,請求惡意服務器,發送用戶數據
- 攻擊者就可以竊取用戶的數據,以此冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操作。
如何應對 XSS 攻擊?
- 對輸入進行過濾,過濾標籤等,只允許合法值。
- HTML 轉義
- 對於鏈接跳轉,如
<a href="xxx"
等,要校驗內容,禁止以 script 開頭的非法鏈接。 - 限制輸入長度
61.對稱加密與非對稱加密有什麼區別?
對稱加密:指加密和解密使用同一密鑰,優點是運算速度較快,缺點是如何安全將密鑰傳輸給另一方。常見的對稱加密算法有:DES、AES 等。
非對稱加密:指的是加密和解密使用不同的密鑰(即公鑰和私鑰)。公鑰與私鑰是成對存在的,如果用公鑰對數據進行加密,只有對應的私鑰才能解密。常見的非對稱加密算法有 RSA。
62.RSA和AES算法有什麼區別?
-
RSA
採用非對稱加密的方式,採用公鑰進行加密,私鑰解密的形式。其私鑰長度一般較長,由於需要大數的乘冪求模等運算,其運算速度較慢,不合適大量數據文件加密。
-
AES
採用對稱加密的方式,其祕鑰長度最長只有256個比特,加密和解密速度較快,易於硬件實現。由於是對稱加密,通信雙方在進行數據傳輸前需要獲知加密密鑰。
參考:
[2]. 小林coding 《圖解網絡》
[4]. 艾小仙 《我要進大廠》
[5]. 《圖解HTTP》
[6]. 淺析DNS域名解析過程
[8]. 計算機網絡
[9]. 謝希仁編著《計算機網絡》
[10].《圖解TCP/IP》
[11].TCP的可靠性傳輸是如何保證的
[12].前端安全系列(一):如何防止XSS攻擊?