1. 請簡述TCP和HTTP的定義與基本概念
- TCP:即傳輸控制協議(Transmission Control Protocol),是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。它為互聯網中的數據通信提供穩定的傳輸機制,在不可靠的IP層之上,通過確認、重傳和錯誤檢測等技術確保數據正確到達。比如在文件傳輸場景中,TCP保證文件的每個字節都能準確無誤地從源端傳輸到目的端。
- HTTP:超文本傳輸協議(HyperText Transfer Protocol),是一個在計算機世界里專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規范。常見的網頁瀏覽就是基于HTTP協議,瀏覽器向服務器發送HTTP請求獲取網頁資源,服務器返回對應的HTTP響應。
2. TCP是如何保證數據的可靠性的
TCP通過多種機制保證數據可靠性:
- 序列號與確認應答:TCP為每個發送的字節編號,接收方收到數據后,會發送ACK確認包給發送方,ACK包中包含確認號,告知發送方下一個期望接收的數據字節序號。通過這種方式,發送方可以確認數據是否被正確接收。
- 超時重傳:發送方發送數據后會啟動一個定時器,如果在規定時間內沒有收到對應的ACK確認,就會認為數據丟失,重新發送該數據。例如,在網絡不穩定時,數據包可能丟失,超時重傳機制確保數據最終能被送達。
- 流量控制:利用滑動窗口機制,接收方通過在ACK包中告知發送方自己的接收窗口大小(即還能接收的數據量),發送方根據接收窗口大小控制發送速率,避免發送過快導致接收方緩沖區溢出。
- 擁塞控制:包括慢啟動、擁塞避免、快速重傳和快速恢復等算法。發送方維護一個擁塞窗口,根據網絡擁塞情況動態調整。如在網絡擁塞時,減少數據發送量,防止網絡進一步惡化。
3. 說一說TCP的三次握手過程,為什么是三次握手
三次握手是建立TCP連接的過程:
- 第一次握手:客戶端向服務器發送SYN(同步序列編號)包,該包中包含客戶端的初始序列號(例如x),此時客戶端進入SYN_SENT狀態,表明客戶端希望與服務器建立連接。
- 第二次握手:服務器接收到客戶端的SYN包后,向客戶端發送SYN - ACK包。這個包包含兩部分,一是對客戶端SYN的確認(ACK = x + 1),二是服務器自己的初始序列號(例如y),此時服務器進入SYN_RCVD狀態。
- 第三次握手:客戶端收到服務器的SYN - ACK包后,向服務器發送ACK包,確認收到服務器的SYN - ACK(ACK = y + 1),此時客戶端和服務器都進入ESTABLISHED狀態,連接建立成功。
TCP需要三次握手主要有兩個原因:
- 防止舊的重復連接引起混亂:在網絡狀況復雜或較差時,發送方可能會連續發送多次建立連接請求。若只有兩次握手,接收方無法判斷請求是正常的還是過期的,可能導致錯誤連接。三次握手能讓雙方確認對方收到了自己的初始序列號,避免這種情況。
- 同步初始化序列號:TCP需要初始化序列號保證消息順序。兩次握手無法確認序列號是否正常,四次握手則會浪費系統資源,三次握手是最優解。
4. 請闡述HTTP常見的請求方法及其區別,比如GET和POST
HTTP常見的請求方法有GET、POST、PUT、DELETE、HEAD等,其中GET和POST區別如下:
- 語義用途:
- GET:從服務器獲取指定資源,是只讀操作。例如在瀏覽器中輸入網址訪問網頁,就是使用GET方法獲取網頁資源。
- POST:根據請求負荷(報文body)對指定資源做出處理,通常用于新增或提交數據,如用戶注冊、表單提交數據等場景。
- 安全性與冪等性:
- GET:從RFC規范定義看,GET方法安全且冪等。安全指不會破壞服務器資源,冪等指多次執行操作結果相同。實際開發中若用GET實現新增或刪除數據,則不具備安全和冪等性。
- POST:因為會修改服務器資源,所以不安全,且多次提交可能創建多個資源,不冪等。但實際若用POST實現查詢數據,則安全且冪等。
- 數據傳輸位置與可見性:
- GET:數據通過URL的查詢參數傳遞,在瀏覽器地址欄可見。例如:
https://example.com/search?q=apple
,其中q=apple
就是查詢參數。 - POST:數據放在請求體(body)中傳輸,瀏覽器地址欄不可見,但抓包工具可查看。
- GET:數據通過URL的查詢參數傳遞,在瀏覽器地址欄可見。例如:
- 緩存性:
- GET:可被緩存,瀏覽器和代理服務器(如Nginx)都能對GET請求的數據做緩存,且瀏覽器中GET請求可保存為書簽。
- POST:大部分實現中不可緩存,瀏覽器一般不會緩存POST請求,也不能保存為書簽。
5. 當在瀏覽器中輸入一個URL并回車后,從網絡層面描述計算機做了哪些工作步驟
- DNS解析:瀏覽器首先檢查自身緩存,看是否有該URL對應的IP地址。若沒有,則向本地DNS服務器發送查詢請求。本地DNS服務器若緩存中有記錄,直接返回IP;沒有則向根DNS服務器、頂級域名服務器等依次查詢,最終獲取到目標URL對應的IP地址。
- TCP連接建立:瀏覽器獲取IP地址后,與目標服務器建立TCP連接,通過三次握手過程(客戶端發送SYN包、服務器返回SYN - ACK包、客戶端再發送ACK包),成功建立可靠連接。
- HTTP請求發送:TCP連接建立后,瀏覽器構建HTTP請求報文,包括請求行(如GET /index.html HTTP/1.1)、請求頭(如User - Agent、Accept等),若為POST請求還會有請求體。然后將請求報文通過TCP連接發送給服務器。
- 服務器處理請求與響應:服務器接收到HTTP請求后,根據請求的URL和方法,找到對應的資源或執行相應的業務邏輯。處理完成后,構建HTTP響應報文,包含狀態行(如HTTP/1.1 200 OK)、響應頭(如Content - Type、Content - Length等)和響應體(如網頁的HTML內容),并通過TCP連接返回給瀏覽器。
- TCP連接關閉:瀏覽器接收完響應數據后,若不需要再與服務器通信,會通過四次揮手過程關閉TCP連接(客戶端發送FIN包、服務器返回ACK包、服務器再發送FIN包、客戶端返回ACK包)。
- 瀏覽器渲染頁面:瀏覽器根據HTTP響應中的Content - Type等信息,對響應體中的數據進行解析和渲染。若響應內容是HTML頁面,瀏覽器會解析HTML、CSS和JavaScript,構建DOM樹,渲染頁面并展示給用戶。
6. 簡述HTTP協議的無狀態性及其帶來的問題與解決方案
- 無狀態性定義:HTTP協議的無狀態性指服務器不保留關于客戶端的任何狀態信息。每個HTTP請求都是獨立的,服務器無法區分這是同一個客戶端的連續請求還是不同客戶端的請求。例如,用戶在一個頁面登錄后,再訪問該網站的其他頁面,服務器無法直接知道該用戶已登錄。
- 帶來的問題:在需要跟蹤用戶狀態的應用場景中,如電商購物車、用戶登錄狀態保持等,無狀態性使得服務器難以處理。每次請求都需額外機制來識別用戶身份和狀態,增加開發復雜度。
- 解決方案:
- Cookie:服務器在HTTP響應頭中添加Set - Cookie字段,將一些狀態信息(如用戶ID、登錄狀態標識等)發送給客戶端。客戶端收到后,在后續的HTTP請求頭中帶上Cookie字段,服務器通過解析Cookie來識別用戶狀態。
- Session:服務器為每個客戶端分配一個唯一的Session ID,通常通過Cookie將Session ID發送給客戶端。服務器在內存或存儲中維護Session數據,客戶端每次請求時,服務器根據Session ID找到對應的Session數據,獲取用戶狀態等信息。
- Token:常用于前后端分離的應用中。服務器驗證用戶身份后,生成一個Token(如JWT,JSON Web Token),包含用戶身份等信息,返回給客戶端。客戶端在后續請求中,將Token放在請求頭或其他位置發送給服務器,服務器通過驗證Token來確認用戶身份和權限。
7. 講講HTTP1.0和HTTP1.1的主要區別
- 連接方式:
- HTTP1.0:只支持短連接,瀏覽器每次請求都需與服務器建立一個TCP連接,服務器完成請求處理后立即斷開TCP連接。這意味著對于包含多個資源(如多個圖片)的網頁,會頻繁建立和斷開TCP連接,增加開銷和延遲。
- HTTP1.1:支持持久連接(默認開啟),在一個TCP連接上可傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲。一個包含許多圖像的網頁文件的多個請求和應答可在一個連接中傳輸,但每個單獨的網頁文件的請求和應答仍需使用各自的連接。通過設置
Connection: Keep - Alive
頭字段開啟持久連接。
- Host字段:
- HTTP1.0:請求消息中的URL沒有傳遞主機名(hostname),因為當時認為每臺服務器都綁定一個唯一的IP地址。
- HTTP1.1:增加了
Host
字段,隨著虛擬主機技術發展,一臺物理服務器上可能存在多個共享一個IP地址的虛擬主機。通過Host
字段,服務器能知道客戶端請求的具體虛擬主機,如Host: www.example.com
。
- 緩存處理:
- HTTP1.0:緩存功能有限,對緩存的控制不夠精細。
- HTTP1.1:引入了更多緩存相關的字段和機制,如
Cache - Control
頭字段,可設置多種緩存策略,包括緩存過期時間、是否可緩存等,比HTTP1.0中簡單的Expires
字段更靈活和強大。
- 錯誤處理:
- HTTP1.0:錯誤狀態碼相對較少,對一些錯誤情況的描述不夠細致。
- HTTP1.1:定義了更多詳細的錯誤狀態碼,如409 Conflict(表示請求與資源當前狀態沖突)、410 Gone(表示資源已永久刪除)等,能更準確地反饋服務器處理請求時遇到的問題。
8. 描述一下HTTP請求和響應的報文格式
- HTTP請求報文格式:
- 請求行:由請求方法(如GET、POST)、請求URL和HTTP協議版本組成,例如
GET /index.html HTTP/1.1
。 - 請求頭:包含一系列鍵值對,用于傳遞關于客戶端環境、請求內容等信息。常見的請求頭有
User - Agent
(用于標識客戶端類型,如瀏覽器名稱和版本)、Accept
(聲明客戶端可接受的數據類型)、Accept - Encoding
(聲明可接受的壓縮方法)、Cookie
(用于傳遞客戶端存儲的Cookie信息)等。每個請求頭占一行,格式為Header - Name: Header - Value
。 - 空行:請求頭和請求體之間用一個空行分隔,標識請求頭結束。
- 請求體:GET請求一般沒有請求體,POST請求時,請求體包含要提交給服務器的數據,如表單數據、JSON格式數據等。數據格式根據
Content - Type
頭字段指定,例如application/x - www - form - urlencoded
表示表單數據,application/json
表示JSON格式數據。
- 請求行:由請求方法(如GET、POST)、請求URL和HTTP協議版本組成,例如
- HTTP響應報文格式:
- 狀態行:由HTTP協議版本、狀態碼和狀態描述組成,例如
HTTP/1.1 200 OK
。狀態碼表示請求處理的結果,如200表示成功,404表示資源未找到。 - 響應頭:同樣是一系列鍵值對,用于傳遞關于服務器環境、響應內容等信息。常見的響應頭有
Content - Type
(表示響應內容的數據類型,如text/html
表示HTML頁面)、Content - Length
(表示響應內容的長度)、Set - Cookie
(用于在客戶端設置Cookie)、Cache - Control
(控制緩存策略)等。 - 空行:響應頭和響應體之間用空行分隔。
- 響應體:包含服務器返回給客戶端的數據,如HTML頁面內容、圖片二進制數據、JSON格式的API響應數據等,具體內容根據請求的資源和服務器處理結果而定。
- 狀態行:由HTTP協議版本、狀態碼和狀態描述組成,例如