1. 計算機網(wǎng)絡(luò)體系模型
- 物理層:建立、維護、斷開物理連接。
- 數(shù)據(jù)鏈路層:建立邏輯連接、進行硬件地址尋址、差錯校驗等功能。
- 網(wǎng)絡(luò)層:進行邏輯地址尋址,實現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇。
- 傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號,以及流控和差錯校驗。
- 會話層:建立、管理、終止會話,(在五層模型里面已經(jīng)合并到了應(yīng)用層)
會話的一端是本地主機,另一端是遠程主機。 - 表示層:數(shù)據(jù)的表示、安全、壓縮。(在五層模型里面已經(jīng)合并到了應(yīng)用層)
格式有,JPEG、ASCll、EBCDIC、加密格式等。 - 應(yīng)用層:網(wǎng)絡(luò)服務(wù)與最終用戶的一個接口。
[圖片上傳失敗...(image-47b18e-1644856864285)]
[圖片上傳失敗...(image-fbfbf-1644856864285)]
網(wǎng)絡(luò)協(xié)議其實就是端到端的一個通信規(guī)則,有了這些規(guī)則,雙方的溝通才有意義。
2. TCP/IP 的頭部格式
[圖片上傳失敗...(image-bc49f9-1644856864285)]
其中,有幾點比較重要:
-
序列號(seq):數(shù)據(jù)包的序號,通過序號來確認包的連續(xù)性,解決包的亂序問題。 -
響應(yīng)號(ack):針對上面字段的確認序號,比如服務(wù)器接收到客戶端的請求,里面包含了 seq 序號,此時服務(wù)器響應(yīng)回去時,會進行 ack = seq + 1 的字段設(shè)置,表示已接收到的累積數(shù)據(jù)。 -
Window:滑動窗口使用,用來反饋接收方接下來能處理的包大小,防止雙方對數(shù)據(jù)包的處理能力不對等,主要解決了流控問題。 -
TCP Flag:TCP 包的類型,用來輔助 TCP 的階段處理,比如 SYN 表示建立連接,F(xiàn)IN 表示關(guān)閉連接。
3. TCP 的狀態(tài)流轉(zhuǎn)
[圖片上傳失敗...(image-f04cf4-1644856864285)]
4. TCP 的三次握手、四次揮手是怎么樣的?為什么這么設(shè)計?
[圖片上傳失敗...(image-bb666-1644856864285)]
如果我們只進行 2 次握手就建立連接,那么對于 Server 端來講太容易建立起連接了,基本是有客戶端過來,那么 Server 就要建立起連接了。這種情況就會導(dǎo)致連接成本太低,Server 端很容超負載。
四次揮手是因為 TCP 是全雙工的,存在了數(shù)據(jù)發(fā)送與接收兩個行為,在這兩個方向的數(shù)據(jù)流入流出都需要進行關(guān)閉。
5. 什么是半連接?跟它相關(guān)的 SYN 攻擊是怎么樣的?
當(dāng)服務(wù)接收到客戶端請求連接 SYN,然后向客戶端響應(yīng) ACK 和 SYN 后, 就會將連接維護到半連接隊列。當(dāng)客戶端再次回復(fù) ACk 后,當(dāng)前的連接就會被維護到全連接隊列里。
SYN 攻擊是 DOS 攻擊的一種,通過偽造大量的請求建立連接,使得半連接隊列超出最大容量,其他正常的請求無法處理。
6. 四次揮手里的發(fā)起方為什么需要等到 TIME_WAIT 時間才關(guān)閉連接?
TIME_WAIT 是一個定時設(shè)置,在 2*MSL(MSL 表示一個包在網(wǎng)絡(luò)環(huán)境中的生存時間,一般為 2 分鐘, Linux 里為 30s)時間過后就會真正的 CLOSED。
之所以不立即關(guān)閉,主要為了讓被動關(guān)閉方能有足夠的時間接收到最后的 Ack 包,如果沒有接收到,被動方就會重新發(fā)送 Fin 包,重新觸發(fā)主動方發(fā)送最后的 Ack 包。這樣的話,就能盡量保證被動關(guān)閉方盡快關(guān)閉連接了,畢竟主動關(guān)閉方需要承擔(dān)起主要責(zé)任,所以會有 TIME_WAIT 的等待了。
另外一個原因也是怕當(dāng)前連接立馬釋放,有一定概率會重用到當(dāng)前連接標(biāo)識(五元組),而舊的網(wǎng)絡(luò)包由于延遲此時才接收到,就有可能產(chǎn)生包的混亂問題了。
7. TCP 的重傳機制是怎么樣的?
TCP 發(fā)送的包都需要接收方進行一個 Ack 包的響應(yīng),如果在一定時間內(nèi)沒有響應(yīng)的話,那么發(fā)送方就會認為包未能正確到達,需要進行重傳動作。這就是 TCP 的重傳機制。
TCP 里的重傳機制會有一個超時的判斷,這個超時時間并不是很準確,或者說并不是很標(biāo)準,畢竟不同的網(wǎng)絡(luò)環(huán)境,包的到達情況都會是不一樣的。
所以 TCP 會使用一個采樣時間,先記錄了正常情況下一個數(shù)據(jù)包從發(fā)送到響應(yīng)確認這么一來一回的時間,即所謂的 RTT(Round Trip Time) 時間,根據(jù)這個時間進行一些公式計算,得到了超時時間的值:RTO(Retransmission TimeOut)
對于重傳機制,還有另外一種觸發(fā)機制。上面的情況屬于發(fā)送方去探知發(fā)送情況,有另一種情況是接收方能探知的。比如發(fā)送方發(fā)送了 1, 2, 3 的包,但實際上接收方只接收到 1 和 3,一直沒能收到 2 這個包,那此時接收方就會連續(xù)響應(yīng)三個 關(guān)于 2 的 ack 包。
當(dāng)發(fā)送方收到這么一個連續(xù)的 3 個 ack 包后,就知道需要重傳 2 了,此時就不需要等到 2 的超時未確認觸發(fā),可以提前的重傳 2 這個包了。
8. 介紹下 TCP 的流量控制,滑動窗口是怎么樣的?
TCP 采用滑動窗口進行了流量的控制,所謂的滑動窗口即在發(fā)送方和接收方各自維護了一個窗口,在這個窗口里將會維護對應(yīng)的數(shù)據(jù)包,以感知當(dāng)前的數(shù)據(jù)處理情況。
在接收方這邊的窗口稱之為接收窗口,它具體表示當(dāng)前所能接收的數(shù)據(jù)包大小,計算公式為:當(dāng)前最大可接收緩沖區(qū)大小 - 當(dāng)前已接收的大小,在連接建好的開始一般為 65535 字節(jié)。
在計算出可接收大小后,接收方就會將此值設(shè)置在 TCP 頭部里的 Window 字段,然后響應(yīng)回發(fā)送方,發(fā)送方也就知道了當(dāng)前所能允許發(fā)送的數(shù)據(jù)包大小了。
在發(fā)送方這邊的窗口稱之為發(fā)送窗口,按正常邏輯來講,發(fā)送窗口維護的是即將要發(fā)送的數(shù)據(jù),即根據(jù)剛剛反饋回來的接收窗口大小計算出的發(fā)送數(shù)據(jù)。
但由于一個數(shù)據(jù)包的發(fā)送需要有一個 ACK 響應(yīng)才算完整流程,所以對于這些“已發(fā)送未響應(yīng)”的數(shù)據(jù)也應(yīng)該納入到發(fā)送窗口的管理,并且只有真的 ACK 響應(yīng)回來,才能繼續(xù)下個數(shù)據(jù)包的準備發(fā)送。
[圖片上傳失敗...(image-8f81f8-1644856864285)]
需要注意的是,如果發(fā)送方接收到的 Window 大小為 0,則表示當(dāng)前的接收方已經(jīng)無能力處理新的包了,此時發(fā)送方就不會再下發(fā)數(shù)據(jù)了,直到接收方發(fā)送一個窗口通告,才繼續(xù)數(shù)據(jù)的發(fā)送。
但此時需要考慮一種情況,就是接收方由于網(wǎng)絡(luò)問題沒能將窗口通告送達發(fā)送方,那此時發(fā)送方就會一直干等著了.所以對于發(fā)送方來講,會啟動窗口探知動作,要求接收方 ACK 它當(dāng)前的接收窗口大小,如果超過 3 次的探知動作,則直接斷開連接了。
9. TCP 對于網(wǎng)絡(luò)環(huán)境的擁塞是怎么感知控制?
TCP 協(xié)議抽象出了擁塞窗口(cwnd)的概念,它會根據(jù)當(dāng)前的網(wǎng)絡(luò)擁塞程度進行動態(tài)的調(diào)整。由于加入了擁塞情況的考慮,上面我們提到過的發(fā)送窗口則不能僅僅只考慮接收窗口這個因素了,需要進行 min(擁塞窗口,接收窗口)的選擇發(fā)送了。
10. MTU 和 MSS 是指什么?
MSS 表示 網(wǎng)絡(luò)傳輸數(shù)據(jù)的最大值,如果 MSS 加上包頭大小,則表示網(wǎng)絡(luò)傳輸最大報文:MTU 。
在 Internet 這種互聯(lián)網(wǎng)中,一般 MTU 定義為 576 字節(jié),減去 TCP、IP 的包頭 40 字節(jié),則可以得到 MSS = 536 字節(jié)的值;而在以太網(wǎng)這種局域網(wǎng)里,一般 MTU 會大點:1500 字節(jié),MSS 為 1460 字節(jié)。
11. TCP 的慢啟動是怎么樣的?有哪些環(huán)節(jié)?
當(dāng)連接建立完畢,開始傳輸數(shù)據(jù)時,TCP 協(xié)議規(guī)定不能一開始就發(fā)送大尺寸的數(shù)據(jù)包,這樣避免了網(wǎng)絡(luò)環(huán)境有問題時,新加入的連接加劇了擁塞狀況。所以,對于新加入的連接而言,需要一點一點的增大數(shù)據(jù)量,這就是所謂的慢啟動。
其中,慢啟動涉及的擁塞窗口計算過程如下:
- 剛開始建立好連接時,擁塞窗口 = 1
- 每當(dāng)接收到一個 ACK 包時,擁塞窗口 = 擁塞窗口 + 1,此時呈線性增加。
- 每當(dāng)經(jīng)過一個 RTT,擁塞窗口 = 擁塞窗口 * 2,此時呈指數(shù)上升趨勢。
12. 什么是擁塞避免?
從慢啟動的算法來看,每經(jīng)過一個 RTT 后,擁塞窗口的增長速度將會變得很厲害,如果沒有進行限制的話,那么很快就會占滿帶寬了。因此, TCP 協(xié)議使用了一個叫慢啟動門限(ssthresh)的變量(一般取 65535 字節(jié))。當(dāng) cwnd(擁塞窗口) 超過該限制后,就會進入所謂的擁塞避免階段了。
在擁塞避免階段,擁塞窗口的計算過程如下:
- 每接收到一個 ACK 包時,擁塞窗口 = 擁塞窗口 + 1/擁塞窗口
- 每當(dāng)經(jīng)過一個 RTT,擁塞窗口 = 擁塞窗口 + 1
從上面的算法可以看出,進入擁塞避免階段后,數(shù)據(jù)包的發(fā)送大小將呈線性增加了。通過這樣的方式,使得 TCP 的傳輸在前期很快,然后再慢慢降下來,達到網(wǎng)絡(luò)最佳值。
13. 當(dāng)擁塞發(fā)生時,TCP 會怎么處理?
在擁塞發(fā)生時,關(guān)于擁塞窗口的計算在不同的 TCP 版本里將會不一樣,主要有以下 3種版本:
Tahoe 版本
Tahoe 版本是 TCP 的最早版本,當(dāng)它發(fā)現(xiàn)需要進行重傳動作,即觸發(fā)了 RTO 超時或發(fā)送方收到三個重復(fù) ACK 包時,此時會進行的動作為:
- sshthresh(慢啟動門限) = cwnd(擁塞窗口) / 2
- cwnd 重置為 1
- 重回慢啟動階段
Reno 版本
Reno 版本進行的動作為:
- sshthresh(慢啟動門限) = cwnd(擁塞窗口) / 2
- cwnd(擁塞窗口) = sshthresh(慢啟動門限) + 3 * MSS (將 3 個重復(fù) ACK 考慮進去)
- 進入快速恢復(fù)階段
其中,快速恢復(fù)階段的計算又如下:
- 當(dāng)重傳的包發(fā)出去后,收到了重傳包的 ACK 后,cwnd(擁塞窗口) = cwnd(擁塞窗口) + 1
- 當(dāng)收到新的數(shù)據(jù)包的 ACK 后,此時快速恢復(fù)過程已結(jié)束,則 cwnd = sshthresh,然后重回擁塞避免階段
NewReno 版本
NewReno 是對 Reno 的改進,主要是優(yōu)化了快速恢復(fù)階段,在 Reno 版本中,所考慮的都是一個包的丟失情況。然而,在實際情況中,一次數(shù)據(jù)窗口的發(fā)送,是有可能出現(xiàn)很多數(shù)據(jù)包丟失情況的。
這樣的話,就會觸發(fā)多次的 cwnd 和 ssthresh 減半動作,一旦 cwnd 降到小于 3 時,即發(fā)送窗口會出現(xiàn)小于 3 的情形,此時將再也觸發(fā)不了 3 次快速重傳動作了,只能依賴 RTO 超時,而一般 RTO 的值是比較大(太小會經(jīng)常觸發(fā)重傳)的,此時整個傳輸速度將會大大降低。
所以 NewReno 會在收到所有數(shù)據(jù)包的確認后才結(jié)束快速恢復(fù)階段,這樣 cwnd 和 sshthresh 就不會輕易被降低了。
NewReno 主要是使用了一個 recover 變量,作為當(dāng)前數(shù)據(jù)窗口中,可能丟包的最大序號。即如果有丟包情況產(chǎn)生,并且大于當(dāng)前的 recover 值,則會更新該值。
當(dāng)收到接收方的 ack 后,會進行 ack_seq 的判斷,如果 ack_seq > recover,此時就可以結(jié)束快速恢復(fù)階段了;如果 ack_seq < recover,則意味著多包丟失,還不能結(jié)束快速恢復(fù)階段。通過這樣的控制,來提高了整個的吞吐量。
14. TCP 里有哪些提高效率的算法或機制?
Nagle 算法
Nagle 算法把多個小數(shù)據(jù)包合并到一個片段,并且等待滿足一定條件后,再一起發(fā)送過去。具體的觸發(fā)條件如下:
- 如果包長度達到 MSS,則允許發(fā)送
- 如果包含 FIN,則允許發(fā)送
- 如果設(shè)置了 TCP_NODELAY,則允許發(fā)送
- 未設(shè)置 TCP_CORK 選項時,若所有發(fā)出去的小數(shù)據(jù)包(包長度小于 MSS)均被確認,則允許發(fā)送
當(dāng)上述條件都未滿足,但發(fā)生了超時(一般為 200ms),則立即發(fā)送。
對于 TCP 協(xié)議來講,默認會啟用 Nagle 算法,降低網(wǎng)絡(luò)負載,減少網(wǎng)絡(luò)擁塞,提高網(wǎng)絡(luò)吞吐。
Delay Ack(延遲確認)
在 TCP 的確認機制里,可以在通信過程中不對每一個 TCP 數(shù)據(jù)包進行單獨的 ACK 包響應(yīng),而是在傳輸數(shù)據(jù)時,順便把 ACK 信息隨數(shù)據(jù)包一起發(fā)送,這樣可以提高網(wǎng)絡(luò)流量利用率。
如果在一定時間內(nèi)(一般 40 ms)沒有數(shù)據(jù)包要發(fā)送,此時就會單獨的進行 ACK 包響應(yīng)。這個過程也被稱為 Delay Ack。
15. TCP 里的粘包與拆包是怎么樣的?
TCP 是面向字節(jié)流的傳輸,它會根據(jù)接收方的包處理能力以及當(dāng)前網(wǎng)絡(luò)的擁塞情況來一部分一部分的加載數(shù)據(jù)發(fā)送,再加上有 Nagle 這種整合小數(shù)據(jù)包的算法存在。所以對于接收方來講,接收到的數(shù)據(jù)有可能是粘合在一起的,也有可能是被拆分開的,即所謂的粘包和拆包。
對于粘包和拆包現(xiàn)象,常用的解決方案有:
- 在包的首部添加當(dāng)前要傳輸?shù)臄?shù)據(jù)包的長度,讓接收方根據(jù)長度去切割。
- 將數(shù)據(jù)包封裝為固定長度,不夠的補 0,讓接收方按固定長度解析。
- 人為的給數(shù)據(jù)包添加邊界,比如在數(shù)據(jù)包結(jié)尾添加特殊字符,當(dāng)解析到特殊字符時,接收方就認為讀取到了一個完整有意義的數(shù)據(jù)段了。
16. TCP 為什么是可靠的?
TCP 的連接和斷開都是雙方互相溝通進行的(三次握手、四次揮手)。在數(shù)據(jù)的傳輸過程中會進行應(yīng)答確認、超時重傳、流量控制、擁塞控制、擁塞避免等手段去保證傳輸?shù)臏蚀_性。
17. TCP 和 UDP 的區(qū)別
TCP 是面向字節(jié)流的可靠連接,而 UDP 是面向數(shù)據(jù)報文的連接,不保證可靠連接,但傳輸比較快。TCP 常用于郵件、文件傳輸這種要求準確性高的場景,而 UDP 常用于視頻直播這種實時傳輸?shù)膱鼍啊?/p>
18. TCP 和 UDP 常見的應(yīng)用層協(xié)議
- TCP 應(yīng)用層:HTTP(超文本傳輸協(xié)議)、FTP(文件傳輸協(xié)議)、SMTP(郵件傳輸)
- UDP 應(yīng)用層:DNS、TFTP(簡單文件傳輸協(xié)議)、NTP(網(wǎng)絡(luò)時間協(xié)議)
19. HTTP 為何是無狀態(tài)的?
HTTP 是基于 TCP 協(xié)議的短連接,按請求-響應(yīng)來通信。每一次的請求都是獨立的,和上次的沒有關(guān)聯(lián)。盡管 TCP 是有狀態(tài)的,但它的狀態(tài)是為了傳輸使用,比如報文序號、發(fā)送窗口大小等輔助信息,這些和 HTTP 的請求沒有關(guān)系。
Http 雖然有 keep-alive 字段控制,但那是為了提高傳輸效率,讓此次的請求連接盡量生命周期長些,不至于頻繁的建立連接-銷毀連接。另外,cookie 會話只是 HTTP 的補充,它是允許關(guān)閉或偽造的,并不是協(xié)議的通信依賴。
20. 從瀏覽器輸入 url 到顯示網(wǎng)頁的整個過程
首先,會根據(jù)域名進行 DNS 的解析,以獲取到服務(wù)器的 IP 地址。拿到 IP 地址后將會和服務(wù)端進行三次握手,建立 TCP 連接。接著將會按照 HTTP 協(xié)議的請求-響應(yīng)來傳輸網(wǎng)頁內(nèi)容。最后,TCP 通過四次揮手結(jié)束連接。
21. HTTP 1.0/1.1/2.0 以及 https 的區(qū)別
HTTP 1.0
每次請求-響應(yīng)都會建立一次 TCP 連接,服務(wù)器處理完后就會斷開 TCP 連接。后面加了 Connection: keep-alive 來延遲 TCP 連接時長,盡量讓請求-響應(yīng)使用同一個連接
HTTP 1.1
- 默認 TCP 持久連接,不需要聲明 Connection 字段,但同一個域名維持的 TCP 持久連接不會太多,一般 6 個;
- 引入管道機制,客戶端可通過同一個 TCP 連接同時發(fā)送多個請求,服務(wù)器再按接收到的請求順序響應(yīng);不過這是偽管道模式,因為在同時發(fā)送多個后,客戶端還是需要阻塞等待服務(wù)器的所有響應(yīng)才能繼續(xù)后續(xù)請求。
- 新增了 PUT、DELETE、OPTIONS 等請求方式
HTTP 2.0
- 采用二進制格式而非文本格式
- 真正的管道模式,非阻塞等待所有響應(yīng),相當(dāng)于全雙工的
- 報文頭會壓縮后再發(fā)送
HTTPS
HTTPS 解決了 HTTP 的安全傳輸問題,在 HTTP 這一層協(xié)議下加入了 SSL 層。即進行了端到端的加密/身份驗證,以保證數(shù)據(jù)的不被竊取篡改。
HTTPS 的流程如下:
[圖片上傳失敗...(image-b619ee-1644856864285)]
22. ping 的原理?
ping 采用了 ICMP 協(xié)議,ICMP 協(xié)議用于在 IP 主機、路由器之間傳遞控制消息??刂葡⑹侵妇W(wǎng)絡(luò)通不通、主機是否可達、路由是否可用等網(wǎng)絡(luò)本身的消息。這些控制消息雖然并不傳輸用戶數(shù)據(jù),但是對于用戶數(shù)據(jù)的傳遞起著重要的作用。
23. 什么是 DOS 攻擊?
DOS:即拒絕服務(wù),其目的是使計算機或網(wǎng)絡(luò)無法提供正常的服務(wù)。最常見的 DoS 攻擊有計算機網(wǎng)絡(luò)帶寬攻擊和連通性攻擊,像 SYN 洪水攻擊也是一種,它利用 TCP 協(xié)議發(fā)送大量的半連接請求,耗費服務(wù)器的 CPU 和內(nèi)存資源。
感興趣的朋友可以搜一搜公眾號「 閱新技術(shù) 」,關(guān)注更多的推送文章。
可以的話,就順便點個贊、留個言、分享下,感謝各位支持!
閱新技術(shù),閱讀更多的新知識。