主要參考:
[面試?網絡] TCP/IP(六):HTTP 與 HTTPS 簡介
[面試?網絡] TCP/IP(五):TCP 協議詳解
[面試?網絡] TCP/IP(四):TCP 與 UDP 協議
[面試?網絡] TCP/IP(三):IP協議相關技術
[面試?網絡] TCP/IP(二):IP協議
[面試?網絡] TCP/IP(一):數據鏈路層
1. 簡介TCP
和 UDP
區別,他們位于哪一層?
A. TCP
和 UDP
區別:
TCP協議:
是面向有連接
的協議,也就是說在使用TCP協議
傳輸數據之前一定要在發送方
和接收方
之間建立連接。建立連接后,通過數據重傳
、流量控制
等功能,TCP協議
能夠正確處理丟包問題,保證接收方
能夠收到數據,同時還能有效利用網絡帶寬
。
UDP協議:
是面向無連接
的協議,它只會把數據傳遞給接收端,但不會關注接收端是否收到數據。
區別:
連接性:
TCP協議
面向有連接
的協議,要先確保發送方
和接收方
之間先建立連接才能進行通信;
UDP協議
是面向無連接
的協議,即發送數據之前不需要建立連接可靠性:
TCP
提供可靠的服務,也就是說,通過TCP
連接傳送的數據,可以保證無差錯
、不丟失
、不重復
、且按序到達
;
UDP
盡最大努力交付,即不保證可靠交付。傳輸內容:
TCP
是面向字節流
,TCP
把數據看成一連串無結構的字節流;
UDP
是面向報文
的,UPD
沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低。服務性質:
每一條TCP
連接都是點到點
的
UPD
支持一對一、一對多、多對一
和多對多
的交互通訊開銷
TCP首部
開銷20
字節;
UDP首部
開銷小,只有8
個字節。信道:
TCP
的邏輯通信信道是全雙工
的可靠信道,
UDP
是不可靠信道。
B. TCP
和UDP
位于OSI七層模型
的第四層
:傳輸層
。
2. 路由器和交換機的工作原理大概是什么,他們分別用到什么協議,位于哪一層?
A.路由器和交換機的工作原理大概是什么
a.交換機
-
二層交換機:
二層交換機
是一種在數據鏈路層
工作的網絡設備
,一般要求支持802.1q(就是劃VLAN)
、SNMP
、限速
、廣播風暴控制
、ACL
、組播
這些常見的功能;它有多個端口,可以連接不同的設備。交換機
根據每個幀中的目標 MAC 地址
決定向哪個端口發送數據,此時它需要參考“轉發表”
轉發表
并非手動設置,而是交換機自動學習得到的。當某個設備向交換機發送幀時,交換機將幀的源MAC 地址
和接口
對應起來,作為一條記錄
添加到轉發表
中。
下圖描述了交換機自學過程
的原理:
交換機工作原理.png 三層交換機:
三層交換機
具有路由器功能
,工作在網絡層
,在二層的基礎上支持如靜態路由
、RIP(矢量路由選擇協議)
、OSPF(鏈路狀態路由選擇協議)
、BGP(邊界網關協議)
、ISIS(分級的鏈接狀態路由協議)
等路由協議,有時候會要求支持MPLS(多協議標簽交換)
、GRE(通用路由封裝協議)
、L2TP(工業標準的Internet隧道協議)
、IPSec(Internet 協議安全性)等隧道協議
。三層交換機上能夠對分組報文根據IP地址
進行轉發。
-
四到七層交換機:
負責處理OSI模型
中從傳輸層
至應用層
的數據。如果用TCP/IP分層模型
來表述,4-7層交換機
就是以傳輸層
及其上面的應用層
為基礎,進行分析數據
,并對其進行特定的處理。
例如:對于并發訪問量
非常大的一個企業級Web站點
,使用一臺服務器不足以滿足前端的訪問需要,這時通常會通過多臺服務器
來分擔,這些服務器前端訪問的入口地址通常只有一個(企業為了使用者的方便,只會向最終的用戶開放一個統一的訪問URL
)。為了能通過同一個URL
將前端訪問分發到后臺多個服務器上,可以在這些服務器的前端加一個負載均衡器
。這種負載均衡器
就是4-7層交換機
的一種。
此外,實際通信當中,人們希望在網絡比較擁堵的時候,優先處理像語音這類對及時性要求較高的通信請求,放緩處理像郵件或數據轉發等稍有延遲也并無大礙的通信請求,這種處理被稱為寬帶控制
,也是4-7層交換機
的重要功能,還有其他很多功能,例如廣域網加速器
,特殊應用訪問加速
以及防火墻
等。
- 路由器:
路由器
工作在網絡層
,完成通過路由控制
將分組數據
發送到目標地址
的功能。支持如靜態路由
、RIP(矢量路由選擇協議)
、OSPF(鏈路狀態路由選擇協議)
、BGP(邊界網關協議)
、EGP(外部網關協議)
、ISIS(分級的鏈接狀態路由協議)
等路由協議。
路由器中保存著路由控制表
,它在路由控制表
中查找目標IP地址
對應的下一個路由器地址
。下圖描述了這一過程:
image.png
主機A
的地址是10.1.1.30
,要把數據發往地址為10.1.2.10
的主機。在主機A
的路由表中,保存了兩個字段,由于目標地址10.1.2.10
與10.1.1.0/24
段不匹配,所以它被發往默認路由10.1.1.1
也就是圖中路由器1的左側網卡的IP地址
。
路由器1
繼續在它自己的路由控制表
中查找目標地址10.1.2.10
,它發現目標地址屬于10.1.2.0/24
這一段,因此將數據轉發至下一個路由器10.1.0.2
,也就是路由器2
的左側網卡的地址。
路由器2
在自己的路由控制表
中查找目標地址10.1.2.10
,根據表中記錄將數據發往10.1.2.1接口
,也就是自己的右側網卡
的IP地址
。主機B
檢查目標IP地址
和自己相同,于是接收數據。
3. 描述TCP 協議三次握手,四次釋放的過程。
A. TCP 三次握手:
圖片取自:TCP三次握手和四次揮手深入實踐
第一次握手:
客戶端
將標志位SYN
置為1
,隨機產生一個序列值seq = x
,并將該數據包發送給服務端
,客戶端
進入SYN_SENT
狀態,等待服務端
確認。第二次握手:
服務端·收到數據包后由
標志位SYN=1
,知道客戶端
請求建立連接,服務端
將標志位SYN
和ACK
都置為1
,ack = x + 1
,隨機產生一個值seq = y
, 并將該數據包發送給客戶端
以確認連接請求,服務端
進入SYN_RCVD
狀態。第三次握手:
客戶端
收到確認后,檢查ack
是否為x+1
,ACK
是否為1
,如果正確將標志位ACK
置為1
,ack = y + 1
, 并將該數據包發送給服務端
,服務端
檢查ack
是否為y+1
,ACK
是否為1
,如果都正確則連接建立成功,客戶端
和服務端
進入ESTABLISHED
狀態,完成三次握手,隨后客戶端
與服務端
之間開始進行數據傳輸。
B. TCP 四次揮手:
圖片取自:TCP三次握手和四次揮手深入實踐
第一次揮手:
客戶端
發出連接釋放報文
,并且停止發送數據。將釋放數據報文首部
的FIN
置為1
,序列號seq
置為u
(等于前面已經傳送過來的數據的最后一個字節的序號加1
),此時,客戶端
進入FIN-WAIT-1(終止等待1)
狀態。TCP
規定,FIN
報文段即使不攜帶數據,也要消耗一個序號。第二次揮手:
服務端
收到報文后,檢查到首部的FIN
為1
,知道客戶端
請求釋放連接
,服務端
發出確認報文
,并將報文首部的ACK
置為1
,ack
置為u + 1
,并且帶上自己的序列號v
,此時服務端進入CLOSE-WAIT(關閉等待狀態)
。客戶端
收到服務端
的確認報文
后,檢查ACK
是否為1
,ack
是否為u+1
,如果都正確,客戶端進入FIN-WAIT-2(終止等待2)
狀態。等待服務端
發送連接釋放報文
。第三次揮手:
服務端
將最后的數據發送完畢后,就向客戶端
發送連接釋放報文
,FIN=1
,ack = u+1
,序列號
為seq = w
(因為在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號
為seq=w
),此時服務端
進入LASK-ACK(最后確認)
狀態,等待客戶端
確認。第四次揮手:
客戶端
接收服務器
的報文后,檢查FIN
為1
,知道服務端
請求釋放連接
,發出確認報文
,ACK = 1
,ack = w + 1
,seq = u + 1
, 此時客戶端
進入TIME-WAIT(時間等待)
狀態。服務端
只要收到客戶端
發出的確認報文
,檢查ACK
是否為1
,ack
是否為w + 1
, 如果都正確,立即進入CLOSE
狀態。
4. TCP 協議是如何進行流量控制,擁塞控制的?
A. 如何進行流量控制:
流量控制
以動態調整發送空間大小(滑動窗口)
的形式來反映接收端
接收消息的能力,反饋給發送端
以調整發送速度
,避免發送速度
過快導致的丟包
或者過慢
降低整體性能。這里采用
滑動窗口機制
,一是不用每次發送完成都需要等待收到確認消息才能繼續發送,二是參考接收端
的接收能力,限制發送數據段
大小,避免丟失現象。
B. 如何進行擁塞控制:
- 連接建立的初期,如果
窗口
比較大,發送方
可能會突然發送大量數據,導致網絡癱瘓。因此,在通信一開始時,TCP
會通過慢啟動
算法得出窗口的大小,對發送數據量進行控制。
流量控制
是由發送方
和接收方
共同控制的。剛剛我們介紹了接收方
會把自己能夠承受的最大窗口長度
寫在TCP 首部
中,實際上在發送方
這里,也存在流量控制
,它叫擁塞窗口
。TCP 協議中的窗口是指發送方窗口
和接收方窗口
的較小值。
慢啟動過程如下:
通信開始時,
發送方
的擁塞窗口
大小為1
。每收到一個ACK
確認后,擁塞窗口
翻倍。由于
指數級增長
非常快,很快地,就會出現確認包
超時。(超時是因為數據量大導致網絡擁塞)此時設置一個
“慢啟動閾值”
,它的值是當前擁塞窗口
大小的一半。同時將
擁塞窗口大小
設置為1
,重新進入慢啟動過程
。由于現在
“慢啟動閾值”
已經存在,當擁塞窗口
大小達到閾值
時,不再翻倍,而是線性增加
。隨著
窗口
大小不斷增加,可能收到三次重復確認
應答,進入“快速重發”
階段。
(快速重發: 當發送端
連續收到三個重復的ack
時,表示該數據段
已經丟失,需要重發。當收到三個表示同一個數據段的ack
時,不需要等待計時器超時,即重新發送數據段(當時這三個ack要在超時之前到達發送端),因為能夠收到接收端
的ack確認信息,所以數據段只是單純的丟失,而不是因為網絡擁塞
導致,)這時候,
TCP
將“慢啟動閾值”
設置為當前擁塞窗口大小
的一半,再將擁塞窗口大小
設置成閾值大小
(也有說加 3)。擁塞窗口
又會線性增加
,直至下一次出現三次重復確認
應答或超時
。
以上過程可以用下圖概括:
5. 為什么建立連接時是三次握手,兩次行不行?如果第三次握手失敗了怎么處理
A. 為什么是三次握手:
因為在網絡請求中,我們應該時刻記住:“網絡是不可靠的,數據包是可能丟失的”。
假設沒有第三次確認,
客戶端
向服務端
發送了SYN
,請求建立連接。由于延遲,服務端沒有及時收到這個包。于是客戶端
重新發送一個SYN
包。回憶一下介紹TCP 首部
時提到的序列號
,這兩個包的序列號顯然是相同的。假設服務端接收到了
第二個 SYN 包
,建立了通信,一段時間后通信結束,連接被關閉。這時候最初被發送的SYN 包
剛剛抵達服務端
,服務端
又會發送一次ACK
確認。由于兩次握手就建立了連接,此時的服務端
就會建立一個新的連接,然而客戶端
覺得自己并沒有請求建立連接,所以就不會向服務端
發送數據。從而導致服務端
建立了一個空的連接,白白浪費資源。在三次握手的情況下,
服務端
直到收到客戶端
的應答后才會建立連接。因此在上述情況下,客戶端
會接受到一個相同的ACK 包
,這時候它會拋棄這個數據包,不會和服務端
進行第三次握手,因此避免了服務端
建立空的連接
。
B. 第三次握手失敗了怎么處理
按照
TCP 協議
處理丟包的一般方法,服務端
會重新向客戶端
發送數據包
,直至收到ACK 確認
為止。但實際上這種做法有可能遭到SYN 泛洪攻擊
。所謂的泛洪攻擊
,是指發送方
偽造多個 IP 地址
,模擬三次握手
的過程。當服務器
返回ACK
后,攻擊方故意不確認,從而使得服務器不斷重發ACK
。由于服務器
長時間處于半連接狀態
,最后消耗過多的CPU
和內存資源
導致死機。正確處理方法是
服務端
發送RST 報文
,進入CLOSE
狀態。這個RST
數據包的TCP
首部中,控制位中的RST 位
被設置為1
。這表示連接信息
全部被初始化,原有的TCP
通信不能繼續進行。客戶端如果還想重新建立TCP
連接,就必須重新開始第一次握手。
6. 關閉連接時,第四次握手失敗怎么處理?
實際上,在第三步
中,客戶端
收到FIN 包
時,它會設置一個計時器
,等待相當長的一段時間。如果客戶端
返回的ACK
丟失,那么服務端
還會重發FIN
并重置計時器
。假設在計時器
失效前服務器
重發的 FIN 包
沒有到達客戶端
,客戶端
就會進入 CLOSE
狀態,從而導致服務端
永遠無法收到 ACK 確認
,也就無法關閉連接
。
示意圖如下:
7. 為什么TCP握手是三次,揮手卻是四次?(假設客戶端主動,服務器端被動)
在TCP
三次握手中,服務器端的SYN
和ACK
是放在一個TCP報文段
中向客戶端
發送的,而在斷開連接的過程中,服務器端
向客戶端
發送的ACK
和FIN
是是分別在兩個不同的TCP
報文段中。這是因為在服務器端
接收到客戶端
的FIN
后,服務器端
可能還有數據要傳輸,所以先發送ACK
,服務器端
把數據發完之后就可以發送FIN
斷開連接了。
7. 你怎么理解分層和協議?
A. 如何理解分層
分層的理由:
獨立性
通過分層,每一層值接受下一層提供的特定服務,并且負責為上一層提供特定服務,上下層之間進行交互所遵循的約定叫“接口”,同一層之間的交互所遵循的約定叫做“協議”。每一層可以獨立使用,及時系統中某些層次發生變化,也不會波及系統。靈活性好
對于任何一層的改動,只要上下層接口不變,都不會造成系統的問題,有利于每一層功能的擴展和變動。易于實現和維護
將大問題簡化為小問題,大系統簡化為小層次。比如將網絡的通信過程劃分為小一些、簡單一些的部件,因此有助于各個部件的開發、設計和故障排除。能促進標準化工作
通過分層,定義在模型的每一層實現什么功能,有利于鼓勵產業的標準化,同時允許多個供應商進行開發。
B. 分層的原則
- 各個層之間有清晰的邊界,便于理解;
- 每個層實現特定的功能;
- 層次的劃分有利于國際標準協議的制定;
- 層的數目應該足夠多,以避免各個層功能重復
B. 如何理解協議
協議
實際上是一種通信雙方共同遵守
的規范
。比如我需要把性別
和年齡
傳遞給另外一臺主機,那么我可以定義一個"A 協議"
,協議規定數據的前 4 個字節
表示性別
,后四個字節
表示年齡
。這樣對方主機
接收時就知道前 4 個字節
是性別
,而不會錯把它當成年齡
來處理。
協議
的規范和共同遵守,有利于各個分層之間的交流和處理,也有利于促進協議
的標準化過程
。
8. HTTP 請求中的 GET 和 POST 的區別,Session 和 Cookie 的區別。
A. HTTP 請求中的 GET 和 POST 的區別
GET
請求通常用于查詢、獲取數據
,而 POST
請求則用于發送數據
,除了用途上的區別,它們還有以下這些不同:
-
GET
后退按鈕/刷新無害,POST
數據會被重新提交(瀏覽器應該告知用戶數據會被重新提交)。 -
GET
書簽可收藏,POST
為書簽不可收藏。 -
GET
能被緩存,POST
不能緩存 。 -
GET
編碼類型application/x-www-form-url
,POST
編碼類型encodedapplication/x-www-form-urlencoded
或multipart/form-data
。為二進制數據使用多重編碼
。 -
GET
歷史參數保留在瀏覽器歷史中。POST
參數不會保存在瀏覽器歷史中。 -
GET
對數據長度有限制,當發送數據時,GET
方法向URL
添加數據;URL
的長度是受限制的(URL
的最大長度是2048
個字符)。POST
無限制。 -
GET
只允許ASCII
字符。POST
沒有限制。也允許二進制數據。與POST
相比, -
GET
的安全性較差,因為所發送的數據是URL
的一部分。在發送密碼或其他敏感信息時絕不要使用GET
!POST
比GET
更安全,因為參數不會被保存在瀏覽器歷史或web 服務器日志
中。GET
的數據在URL
中對所有人都是可見的。POST
的數據不會顯示在URL
中。
注意:
POST
請求僅比GET
請求略安全一點,它的數據不在URL
中,但依然以明文的形式
存放于HTTP
的請求頭中。
B.Cookie 和 Session
HTTP
是一種無狀態
的連接,客戶端
每次讀取web 頁面
時,服務器
都會認為這是一次新的會話
。但有時候我們又需要持久保持
某些信息,比如登錄時的用戶名、密碼
,用戶上一次連接時的信息等。這些信息就由 Cookie
和Session
保存。
這兩者的根本性區別在于,cookie
保存在客戶端
上,而 session
則保存在服務器
中。由此我們還可以拓展出以下結論:
-
cookie
相對來說不安全,瀏覽器可以分析本地的cookie
進行cookie
欺騙。 -
session
可以設置超時時間,超過這個時間后就失效,以免長期占用服務端
內存。 - 單個
cookie
的大小有限制(4 Kb)
,每個站點的cookie
數量一般也有限制(20個)
。 -
客戶端
每次都會把cookie
發送到服務端
,因此服務端
可以知道cookie
,但是客戶端
不知道session
。
當服務器
接收到cookie
后,會根據cookie
中的 SessionID
來找到這個客戶的 session
。如果沒有,則會生成一個新的 SessionID
發送給客戶端。
9. 談談你對 HTTP 1.1,2.0 和 HTTPS 的理解。
一、HTTP
HTTP(超文本傳輸協議,HyperText Transfer Protocol)
是應用層
的協議,目前在互聯網中應用廣泛。
它被設計用于Web瀏覽器
和Web服務器
之間的通信,但它也可以用于其他目的。 HTTP
遵循經典的客戶端-服務端模型
,客戶端打開一個連接以發出請求,然后等待它收到服務器端
響應。HTTP
是
無狀態協議
,意味著服務器
不會在兩個請求之間保留任何數據(狀態)。
二、HTTP1.0 ——構建可擴展性
HTTP 1.0
規定瀏覽器
與服務器
只保持短暫的連接,瀏覽器
的每次請求都需要與服務器
建立一個TCP連接
,服務器
完成請求處理后立即斷開TCP連接
,服務器不跟蹤每個客戶也不記錄過去的請求。
三、HTTP1.1
——標準化的協議
HTTP/1.0
的多種不同的實現運用起來有些混亂,HTTP1.1
是第一個標準化版本,重點關注的是校正HTTP1.0
設計中的結構性缺陷:
連接可以重復使用,節省了多次打開它的時間,以顯示嵌入到單個原始文檔中的資源。
增加流水線操作,允許在第一個應答被完全發送之前發送第二個請求,以降低通信的延遲。
支持響應分塊。
引入額外的緩存控制機制。
引入內容協商,包括語言,編碼,或類型,并允許客戶端和服務器約定以最適當的內容進行交換。
添加Host 頭,能夠使不同的域名配置在同一個IP地址的服務器。
安全性得到了提高
在http1.1
中,client
和server
都是默認對方支持長鏈接的, 如果不希望使用長鏈接,則需要在header中
指明connection:close
;
四、HTTP2.0——為了更優異的表現
HTTP/2.0
在HTTP/1.1
有幾處基本的不同:
-
HTTP2
是二進制協議
而不是文本協議
。不再可讀和無障礙的手動創建,改善的優化技術現在可被實施。 - 這是一個復用協議。并行的請求能在同一個鏈接中處理,移除了HTTP/1.x中順序和阻塞的約束。
- 壓縮了headers。因為headers在一系列請求中常常是相似的,其移除了重復和傳輸重復數據的成本。
- 其允許服務器在客戶端緩存中填充數據,通過一個叫服務器推送的機制來提前請求。
五、HTTPS
我們知道HTTP
協議直接使用了TCP
協議進行數據傳輸。由于數據沒有加密,都是直接明文
傳輸,所以存在以下三個風險:
竊聽風險:第三方節點可以獲知通信內容。
篡改風險:第三方節點可以修改通信內容。
冒充風險:第三方節點可以冒充他人身份參與通信。
比如你在手機上打開應用內的網頁時,有時會看到網頁底部彈出了廣告,這實際上就說明你的HTTP
內容被竊聽、并篡改了。
HTTPS
協議旨在解決以上三個風險
,因此它可以:
保證所有信息加密傳輸,無法被第三方竊取。
為信息添加校驗機制,如果被第三方惡意破壞,可以檢測出來。
配備身份證書,防止第三方偽裝參與通信。
HTTPS
的結構如圖所示:
可見它僅僅是在 HTTP
和TCP
之間新增了一個TLS/SSL
加密層,這也印證了一句名言:“一切計算機問題都可以通過添加中間層解決”。
使用HTTPS
時,服務端
會將自己的證書發送給客戶端
,其中包含了服務端
的公鑰。基于非對稱加密
的傳輸過程如下:
- 客戶端使用公鑰將信息加密,密文發送給服務端
- 服務端用自己的私鑰解密,再將返回數據用私鑰加密發回客戶端
- 客戶端用公鑰解密
這里的證書
是服務器
證明自己身份的工具,它由權威的證書頒發機構(CA)
發給申請者。如果證書是虛假的,或者是自己給自己頒發的證書,服務器就會不認可這個證書并發出警告:
總結一下 HTTPS 協議
是如何避免前文所說的三大風險的:
先用
非對稱加密
傳輸密碼,然后用這個密碼對稱加密數據
,使得第三方無法獲得通信內容發送方
將數據的哈希結果
寫到數據中,接收方
解密后對比數據的哈希結果
,如果不一致則說明被修改。由于傳輸數據加密,第三方無法修改哈希結果。由
權威機構頒發
證書,再加上證書校驗
機制,避免第三方偽裝
參與通信.