計算機網路是計算機、軟工類面試的基礎,不管是軟體/硬體開發、技術支援還是測試職位,都會涉及到計算機網路的基礎知識,本文基於筆者之前的面試準備所做的相關知識整理。本文的主要內容:
- OSI 與 TCP/IP 模型
- OSI 七層模型
- OSI 的缺陷
- TCP/IP 五層模型
- TCP 三次握手和四次揮手
- TCP 建立連線
- TCP三次握手,如果兩次握手會怎麼樣?
- TCP 關閉連線
- 為什麼建立連線是三次握手,而關閉連線卻是四次揮手呢?
- 為什麼需要 TIME_WAIT 狀態?
- TCP 協議如何保證可靠傳輸
- HTTP 和 HTTPS
- 基本概念
- HTTPS 和 HTTP 的區別
- HTTP 響應的狀態碼
- HTTP 長連線、短連線
OSI 與 TCP/IP 模型
OSI 七層模型
OSI(Open System Interconnect),即開放式系統互聯。 一般都叫OSI參考模型,是ISO(國際標準化組織)組織在1985年研究的網路互連模型。
OSI定義了網路互連的七層框架(物理層、資料鏈路層、網路層、傳輸層、會話層、表示層、應用層),即ISO開放互連繫統參考模型。
從上到下介紹每層的功能:
- 應用層:OSI參考模型中最靠近使用者的一層,是為計算機使用者提供應用介面,也為使用者直接提供各種網路服務。我們常見應用層的網路服務協議有:HTTP,HTTPS,FTP,POP3、SMTP等。
- 表示層:表示層提供各種用於應用層資料的編碼和轉換功能,確保一個系統的應用層傳送的資料能被另一個系統的應用層識別。如果必要,該層可提供一種標準表示形式,用於將計算機內部的多種資料格式轉換成通訊中採用的標準表示形式。資料壓縮和加密也是表示層可提供的轉換功能之一。
- 會話層:負責建立、管理和終止表示層實體之間的通訊會話。該層的通訊由不同裝置中的應用程式之間的服務請求和響應組成。
- 傳輸層:傳輸層建立了主機端到端的連結,傳輸層的作用是為上層協議提供端到端的可靠和透明的資料傳輸服務,包括處理差錯控制和流量控制等問題。該層向高層遮蔽了下層資料通訊的細節,使高層使用者看到的只是在兩個傳輸實體間的一條主機到主機的、可由使用者控制和設定的、可靠的資料通路。我們通常說的,TCP UDP就是在這一層。埠號既是這裡的“端”。
- 網路層:本層通過IP定址來建立兩個節點之間的連線,為源端的運輸層送來的分組,選擇合適的路由和交換節點,正確無誤地按照地址傳送給目的端的運輸層。就是通常說的IP層。這一層就是我們經常說的IP協議層。IP協議是Internet的基礎。
- 資料鏈路層:將位元組合成位元組,再將位元組組合成幀,使用鏈路層地址 (乙太網使用MAC地址)來訪問介質,並進行差錯檢測。資料鏈路層又分為2個子層:邏輯鏈路控制子層(LLC)和媒體訪問控制子層(MAC)。
- MAC子層處理CSMA/CD演算法、資料出錯校驗、成幀等;
- LLC子層定義了一些欄位使上次協議能共享資料鏈路層。 在實際使用中,LLC子層並非必需的。
- 物理層
實際最終訊號的傳輸是通過物理層實現的。通過物理介質傳輸位元流。規定了電平、速度和電纜針腳。常用裝置有(各種物理裝置)集線器、中繼器、調變解調器、網線、雙絞線、同軸電纜。這些都是物理層的傳輸介質。
OSI 的缺陷
OSI的七層體系結構概念清楚,理論也很完整,但是它比較複雜而且不實用。在這裡順帶提一下之前一直被一些大公司甚至一些國家政府支援的OSI失敗的原因:
- OSI的專家缺乏實際經驗,他們在完成OSI標準時缺乏商業驅動力
- OSI的協議實現起來過分複雜,而且執行效率很低
- OSI制定標準的週期太長,因而使得按OSI標準生產的裝置無法及時進入市場(20世紀90年代初期,雖然整套的OSI國際標準都已經制定出來,但基於TCP/IP的網際網路已經搶先在全球相當大的範圍成功執行了)
- OSI的層次劃分不太合理,有些功能在多個層次中重複出現
TCP/IP 五層模型
TCP/IP五層協議和OSI的七層協議對應關係如下:
- 應用層(application layer)
應用層的任務是通過應用程式間的互動來完成特定網路應用。應用層協議定義的是應用程式(程式:主機中正在執行的程式)間的通訊和互動的規則。對於不同的網路應用需要不同的應用層協議。在網際網路中應用層協議很多,如域名系統DNS,支援全球資訊網應用的HTTP協議,支援電子郵件的SMTP協議等等。我們把應用層互動的資料單元稱為報文。 - 運輸層(transport layer)
運輸層的主要任務就是負責向兩臺主機程式之間的通訊提供通用的資料傳輸服務。應用程式利用該服務傳送應用層報文。“通用的”是指並不針對某一個特定的網路應用,而是多種應用可以使用同一個運輸層服務。由於一臺主機可同時執行多個執行緒,因此運輸層有複用和分用的功能。所謂複用就是指多個應用層程式可同時使用下面運輸層的服務,分用和複用相反,是運輸層把收到的資訊分別交付上面應用層中的相應程式。 運輸層主要使用以下兩種協議:- 傳輸控制協議TCP(Transmisson Control Protocol)--提供面向連線的,可靠的資料傳輸服務。
- 使用者資料協議UDP(User Datagram Protocol)--提供無連線的,盡最大努力的資料傳輸服務(不保證資料傳輸的可靠性)。
- 網路層(network layer)
網路層負責為分組交換網上的不同主機提供通訊服務。在傳送資料時,網路層把運輸層產生的報文段或使用者資料包封裝成分組和包進行傳送。在TCP/IP體系結構中,由於網路層使用IP協議,因此分組也叫IP資料包,簡稱資料包。 這裡要注意:不要把運輸層的“使用者資料包UDP”和網路層的“IP資料包”弄混。另外,無論是哪一層的資料單元,都可籠統地用“分組”來表示。 網路層的另一個任務就是選擇合適的路由,使源主機運輸層所傳下來的分株,能通過網路層中的路由器找到目的主機。
網際網路是由大量的異構(heterogeneous)網路通過路由器(router)相互連線起來的。網際網路使用的網路層協議是無連線的網際協議(Intert Prococol)和許多路由選擇協議,因此網際網路的網路層也叫做網際層或IP層。 - 資料鏈路層(data link layer)
資料鏈路層通常簡稱為鏈路層。兩臺主機之間的資料傳輸,總是在一段一段的鏈路上傳送的,這就需要使用專門的鏈路層的協議。 在兩個相鄰節點之間傳送資料時,資料鏈路層將網路層交下來的IP資料包組裝程幀,在兩個相鄰節點間的鏈路上傳送幀。每一幀包括資料和必要的控制資訊(如同步資訊,地址資訊,差錯控制等)。 在接收資料時,控制資訊使接收端能夠知道一個幀從哪個位元開始和到哪個位元結束。這樣,資料鏈路層在收到一個幀後,就可從中提出資料部分,上交給網路層。 控制資訊還使接收端能夠檢測到所收到的幀中有誤差錯。如果發現差錯,資料鏈路層就簡單地丟棄這個出了差錯的幀,以避免繼續在網路中傳送下去白白浪費網路資源。如果需要改正資料在鏈路層傳輸時出現差錯(這就是說,資料鏈路層不僅要檢錯,而且還要糾錯),那麼就要採用可靠性傳輸協議來糾正出現的差錯。這種方法會使鏈路層的協議複雜些。 - 物理層(physical layer)
在物理層上所傳送的資料單位是位元。物理層的作用是實現相鄰計算機節點之間位元流的透明傳送,儘可能遮蔽掉具體傳輸介質和物理裝置的差異。使其上面的資料鏈路層不必考慮網路的具體傳輸介質是什麼。“透明傳送位元流”表示經實際電路傳送後的位元流沒有發生變化,對傳送的位元流來說,這個電路好像是看不見的。
在網際網路使用的各種協中最重要和最著名的就是TCP/IP兩個協議。現在人們經常提到的TCP/IP並不一定單指TCP和IP這兩個具體的協議,而往往表示網際網路所使用的整個TCP/IP協議族。
TCP 三次握手和四次揮手
TCP建立過程和連結折除過程是由 TCP/IP 協議棧自動建立的。因此開發者並不需要控制這個過程,但是對於理解TCP底層運作機制,相當有幫助。
TCP 建立連線
TCP 建立連線,即所謂三次握手(Three-way Handshake),是指建立一個TCP連線時,需要客戶端和伺服器總共傳送3個包。具體過程如下:
- 客戶端傳送帶有 SYN 標誌的資料包–-一次握手–服務端;
- 服務端傳送帶有 SYN/ACK 標誌的資料包–-二次握手–客戶端;
- 客戶端傳送帶有帶有 ACK 標誌的資料包–-三次握手–服務端。
TCP三次握手,如果兩次握手會怎麼樣?
如果是兩次握手,有這樣一種情況,當 A 傳送一個訊息給 B,但是由於網路原因,訊息被阻塞在了某個節點,然後阻塞的時間超出設定的時間,A 會認為這個訊息丟失了,然後重新傳送訊息。當 A 和 B 通訊完成後,這個被A認為失效的訊息,到達了 B。
對於 B 而言,以為這是一個新的請求連結訊息,就向 A 傳送確認。對於 A 而言,它認為沒有給 B 再次傳送訊息(因為上次的通話已經結束)所有 A 不會理睬 B 的這個確認,但是 B 則會一直等待 A 的訊息。這就導致了 B 的時間被浪費(對於伺服器而言,CPU 等資源是一種浪費),這樣是不可行的,這就是為什麼不能兩次握手的原因了。
所以有了三次握手的修訂,第三次握手看似多餘其實不然,這主要是為了防止已失效的請求報文段突然又傳送到了服務端而產生連線的誤判。
TCP 關閉連線
TCP 連線的拆除需要傳送四個包,因此稱為四次揮手(four-way handshake)。客戶端或伺服器均可主動發起揮手動作,在socket程式設計中,任何一方執行close()操作即可產生揮手操作。
- 客戶端傳送一個 FIN,用來關閉客戶端到伺服器的資料傳送;
- 伺服器收到這個 FIN,它發回一個 ACK,確認序號為收到的序號加 1。和 SYN 一樣,一個 FIN 將佔用一個序號;
- 伺服器關閉與客戶端的連線,傳送一個FIN給客戶端;
- 客戶端發回 ACK 報文確認,並將確認序號設定為收到序號加 1。
為什麼建立連線是三次握手,而關閉連線卻是四次揮手呢?
建立連線時,因為服務端在 LISTEN 狀態下,收到建立連線請求的 SYN 報文後,把 ACK 和 SYN 放在一個報文裡傳送給客戶端。
關閉連線時,當收到對方的 FIN 報文時,僅表示對方不再傳送資料但還能接收收據,我們也未必把全部資料都發給了對方,所以我們可以立即 close,也可以傳送一些資料給對方後,再傳送 FIN 報文給對方表示同意關閉連線。因此我們的 ACK 和 FIN 一般會分開傳送。
為什麼需要 TIME_WAIT 狀態?
從TCP連線關閉的狀態轉換關係可以看出,主動關閉的一方在傳送完對對方 FIN 報文的確認(ACK)報文後,會進入 TIME_WAIT 狀態。TIME_WAIT 狀態也稱為 2MSL 狀態。
什麼是2MSL?MSL 即 Maximum Segment Lifetime,也就是報文最大生存時間,引用《TCP/IP詳解》中的話:它(MSL)是任何報文段被丟棄前在網路內的最長時間。那麼,2MSL 也就是這個時間的 2 倍。最後總結為主動關閉的一方將繼續等待一定時間(2-4分鐘),使兩端的應用程式結束。
為什麼需要 TIME_WAIT 狀態:
- 為實現 TCP 這種全雙工連線的可靠釋放
這樣可讓 TCP 再次傳送最後的 ACK 以防這個 ACK 丟失(另一端超時並重發最後的 FIN)這種 2MSL 等待的另一個結果是這個 TCP 連線在 2MSL 等待期間,定義這個連線的插口(客戶的 IP 地址和埠號,伺服器的 IP 地址和埠號)不能再被使用。這個連線只能在 2MSL 結束後才能再被使用。 - 為使舊的資料包在網路因過期而消失
每個具體 TCP 實現必須選擇一個報文段最大生存時間 MSL。它是任何報文段被丟棄前在網路內的最長時間。
TIME_WAIT 狀態所帶來的影響:
當某個連線的一端處於 TIME_WAIT 狀態時,該連線將不能再被使用。事實上,對於我們比較有現實意義的是,這個埠將不能再被使用。某個埠處於 TIME_WAIT 狀態(其實應該是這個連線)時,這意味著這個 TCP 連線並沒有斷開(完全斷開),那麼,如果你 bind 這個埠,就會失敗。對於伺服器而言,如果伺服器突然 crash 掉了,那麼它將無法再 2MSL 內重新啟動,因為 bind 會失敗。解決這個問題的一個方法就是設定 socket 的 SO_REUSEADDR 選項。這個選項意味著你可以重用一個地址。
TCP 協議如何保證可靠傳輸
TCP協議保證資料傳輸可靠性的方式主要有:
- 校驗和: TCP 將保持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP 將丟棄這個報文段和不確認收到此報文段。
- 確認應答+序列號(累計確認+seq)。接收方收到報文就會確認(累積確認:對所有按序接收的資料的確認),TCP 給傳送的每一個包進行編號,接收方對資料包進行排序,把有序資料傳送給應用層。TCP 的接收端會丟棄重複的資料。
- 流量控制: TCP 連線的每一方都有固定大小的緩衝空間,TCP的接收端只允許傳送端傳送接收端緩衝區能接納的資料。當接收方來不及處理髮送方的資料,能提示傳送方降低傳送的速率,防止包丟失。TCP 使用的流量控制協議是可變大小的滑動視窗協議。 (TCP 利用滑動視窗實現流量控制)
- 擁塞控制: 當網路擁塞時,減少資料的傳送。
- 停止等待協議 也是為了實現可靠傳輸的,它的基本原理就是每發完一個分組就停止傳送,等待對方確認。在收到確認後再發下一個分組。
- 超時重傳: 當 TCP 發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。
HTTP 和 HTTPS
基本概念
HTTP:是網際網路上應用最為廣泛的一種網路協議,是一個客戶端和伺服器端請求和應答的標準(TCP),用於從 WWW 伺服器傳輸超文字到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網路傳輸減少。
HTTPS:是以安全為目標的 HTTP 通道,簡單講是 HTTP 的安全版,即 HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL。 HTTPS協議的主要作用可以分為兩種:一種是建立一個資訊保安通道,來保證資料傳輸的安全;另一種就是確認網站的真實性。
HTTPS 和 HTTP 的區別
- https協議需要到ca申請證照,一般免費證照較少,因而需要一定費用。
- http是超文字傳輸協議,資訊是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
- http 和 https 使用的是完全不同的連線方式,用的埠也不一樣,前者是 80,後者是 443。
- http 的連線很簡單,是無狀態的;HTTPS 協議是由 SSL + HTTP 協議構建的可進行加密傳輸、身份認證的網路協議,比 http 協議安全。
HTTP 響應的狀態碼
作為程式開發人員對於一些伺服器返回的 HTTP 狀態的意思都應該瞭如指掌,只有將這些狀態碼一一弄清楚,工作中遇到的各種問題才能夠處理的得心應手。所以下面就讓我們來了解一下比較常見的 HTTP 狀態碼吧!
-
1xx - 資訊提示 這些狀態程式碼表示臨時的響應。客戶端在收到常規響應之前,應準備接收一個或多個 1xx 響應。如:
- 100:Continue 初始的請求已經接受,客戶應當繼續傳送請求的其餘部分。(HTTP 1.1新)
- 101:Switching Protocols 伺服器將遵從客戶的請求轉換到另外一種協議(HTTP 1.1 新)
-
2xx - 成功 這類狀態程式碼表明伺服器成功地接受了客戶端請求。
- 200 - OK 一切正常,對GET和POST請求的應答文件跟在後面。 - 201 - Created 伺服器已經建立了文件,Location頭給出了它的URL。
- 202 - Accepted 已經接受請求,但處理尚未完成。
-
3xx - 重定向 客戶端瀏覽器必須採取更多操作來實現請求。例如,瀏覽器可能不得不請求伺服器上的不同的頁面,或通過代理伺服器重複該請求。如 304 Not Modified
-
4xx - 客戶端錯誤 發生錯誤,客戶端似乎有問題。例如,客戶端請求不存在的頁面,客戶端未提供有效的身份驗證資訊。如:
- 400 - Bad Request 請求出現語法錯誤。
- 401 - Unauthorized 訪問被拒絕,客戶試圖未經授權訪問受密碼保護的頁面。
-
5xx - 伺服器錯誤 伺服器由於遇到錯誤而不能完成該請求。如:
- 500 - Internal Server Error 伺服器遇到了意料不到的情況,不能完成客戶的請求。
- 502 - Bad Gateway 伺服器作為閘道器或者代理時,為了完成請求訪問下一個伺服器,但該伺服器返回了非法的應答。
HTTP 長連線、短連線
在 HTTP/1.0 中預設使用短連線。也就是說,客戶端和伺服器每進行一次 HTTP 操作,就建立一次連線,任務結束就中斷連線。當客戶端瀏覽器訪問的某個 HTML 或其他型別的 Web 頁中包含有其他的 Web 資源(如 JavaScript 檔案、影像檔案、CSS 檔案等),每遇到這樣一個 Web 資源,瀏覽器就會重新建立一個 HTTP 會話。 而從 HTTP/1.1 起,預設使用長連線,用以保持連線特性。使用長連線的 HTTP 協議,會在響應頭加入這行程式碼:
Connection:keep-alive
複製程式碼
在使用長連線的情況下,當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸 HTTP資料的 TCP 連線不會關閉,客戶端再次訪問這個伺服器時,會繼續使用這一條已經建立的連線。Keep-Alive 不會永久保持連線,它有一個保持時間,可以在不同的伺服器軟體(如 Apache)中設定這個時間。實現長連線需要客戶端和服務端都支援長連線。