網絡基礎 TCP / IP
通常使用的網絡(包括網際網路)是在 TCP / IP 協定族的基礎上運作的,而 HTTP 屬于它内部的一個子集。Web 使用一種名為 HTTP(HyperText Transfer Protocol,超文本傳輸協定)的協定作為規範,完成從用戶端(指通過發送請求擷取伺服器資源的 Web 浏覽器等)到伺服器端等一系列運作流程,而協定是指規則的約定。可以說,Web 是建立在 HTTP 協定上通信的。
協定
計算機與網絡裝置要互相通信,雙方就必須基于相同的方法。比如,探測到通信目标、由哪一邊先發起通信、使用哪種語言進行通信、怎樣結束通信等規則都需要事先确定。不同的硬體、作業系統之間的通信,所有的這一切都需要一種規則,而我們就把這種規則稱為協定。
TCP / IP 協定族
像這樣把與網際網路相關聯的協定集合起來總稱為 TCP / IP,如 HTTP、FTP、DNS、TCP 都為 TCP / IP 協定集合下的協定。
OSI與TCP/IP分層模型
TCP / IP 協定族裡最重要的一點就是分層,分層的好處是隻需把各層之間的接口部分規劃好,每個層次的内部設計就能自由改動,而不會影響到整體。TCP / IP 協定族按層次分别為以下四層:
- 應用層,決定了向使用者提供應用服務時通信的活動。 TCP / IP 協定族内預存了各類通用的應用服務,比如,FTP(File Transfer Protocol,檔案傳輸協定)和 DNS(Domain Name System,域名系統)服務就是其中兩類,HTTP 協定也處于該層;
- 傳輸層,對上層應用層,提供處于網絡連接配接中的兩台計算機之間的資料傳輸。 在傳輸層有兩個性質不同的協定:TCP(Transmission Control Protocol,傳輸控制協定)和 UDP(User Data Protocol,使用者資料報協定);
- 網絡層(又名網絡互連層),用來處理在網絡上流動的資料包。 資料包是網絡傳輸的最小資料機關,該層規定了通過怎樣的路徑(所謂的傳輸路線)到達對象計算機,并把資料包傳送給對方。與對方計算機之間通過多台計算機或網絡裝置進行傳輸時,網絡層起的作用就是在衆多的選項内選擇一條傳輸路線;
- 資料鍊路層(又名資料鍊路層,網絡接口層),用來處理連接配接網絡的硬體部分. 包括控制作業系統、硬體的裝置驅動、NIC(Network Interface Card,網絡擴充卡,即網卡),及光纖等實體可見部分(還包括連接配接器等一切傳輸媒介)。硬體上的範疇均在鍊路層的作用範圍之内。
TCP / IP 通信傳輸流
利用 TCP / IP 協定族進行網絡通信時,會通過分層順序與對方進行通信。發送端從應用層往下走,接收端則往應用層往上走。舉例用 HTTP 來說明:
- 首先作為發送端的用戶端在應用層(HTTP 協定)發出一個想看某個 Web 頁面的 HTTP 請求;
- 接着,為了傳輸友善,在傳輸層(TCP 協定)把從應用層處收到的資料(HTTP 請求封包)進行分割,并在各個封包上打上标記序号及端口号後轉發給網絡層;
- 在網絡層(IP 協定),增加作為通信目的地的 MAC 位址後轉發給鍊路層;
- 這樣一來,發往網絡的通信請求就準備齊全了。接收端的伺服器在鍊路層接收到資料,按序往上層發送,一直到應用層。當傳輸到應用層,才能算真正接收到由用戶端發送過來的 HTTP請求。
發送端在層與層之間傳輸資料時,每經過一層時必定會被打上一個該層所屬的首部資訊。反之,接收端在層與層傳輸資料時,每經過一層時會把對應的首部消去。這種把資料資訊包裝起來的做法稱為封裝(encapsulate)。
OSI參考模型分層說明
OSI參考模型通信過程
- 1、打包資料時,每一層在處理上一層傳過來的資料時,會在資料上附上目前層的首部資訊後傳給下一層;
- 2、解包資料時,每一層在處理下一層傳過來的資料時,會将目前層的首部資訊與資料分開,将資料傳給上一層。
- 3、資料通信過程:
分層 | 每層的操作 |
---|---|
應用層 | 在資料前面加首部,首部包括資料内容、源位址和目标位址,同時也會處理異常的回報資訊。 |
表示層 | 将特有的資料格式轉換為通用的資料格式,同時也會加上表示層的首部資訊以供解析。 |
會話層 | 對何時連接配接,以何種方式連接配接,連接配接多久,何時斷開等做記錄。同時也會加會話層的首部資訊。 |
傳輸層 | 建立連接配接,斷開連接配接,确認資料是否發送成功和執行失敗重發任務。 |
網絡層 | 負責将資料發到目标位址,也包含首部資訊。 |
資料鍊路層 | 通過實體的傳輸媒體實作資料的傳輸。 |
實體層 | 将0/1轉換成實體的傳輸媒體,通過MAC位址進行傳輸。 |
與 HTTP 關系密切的協定 : IP、TCP 和 DNS
- 負責傳輸的 IP 協定,通過 IP 位址和 MAC 位址将資料送往對方。 按層次分,IP(Internet Protocol)網際協定位于網絡層。TCP / IP 協定族中的 IP 指的是網際協定,是一種協定的名稱。IP 協定的作用是把各種資料包傳送給對方。而要保證确實傳送到對方那裡,則需要滿足各類條件。其中兩個重要的條件是 IP 位址和 MAC 位址(Media Access Control Address)。IP 位址指明了節點被配置設定到的位址,MAC 位址是指網卡所屬的固定位址。IP 位址可以和 MAC 位址進行配對。IP 位址可變換,但 MAC 位址基本上不會更改。在網絡上,通信的雙方通常是經過多台計算機和網絡裝置中轉才能連接配接到對方。而在進行中轉時,會利用下一站中轉裝置的 MAC 位址來搜尋下一個中轉目标。這時,會采用 ARP 協定(Address Resolution Protocol),一種用以解析位址的協定,根據通信方的 IP 位址就可以反查出對應的 MAC 位址。在到達通信目标前的中轉過程中,那些計算機和路由器等網絡裝置隻能獲悉很粗略的傳輸路線,這種機制稱為路由選擇(routing);
- 確定可靠性的 TCP 協定,使用了三次握手政策確定資料發送成功。 按層次分,TCP 位于傳輸層,提供可靠的位元組流服務。所謂的位元組流服務(Byte Stream Service)是指,為了友善傳輸,将大塊資料分割成以封包段(segment)為機關的資料包進行管理。而可靠的傳輸服務是指,能夠把資料準确可靠地傳給對方。即 TCP 協定為了更容易傳送大資料才把資料分割,而且 TCP 協定采用三次握手政策。
簡單示意圖:
- 用戶端–發送帶有 SYN 标志的資料包–一次握手–服務端
- 服務端–發送帶有 SYN/ACK 标志的資料包–二次握手–用戶端
- 用戶端–發送帶有帶有 ACK 标志的資料包–三次握手–服務端
- 四次揮手
斷開一個 TCP 連接配接則需要“四次揮手”:
- 用戶端-發送一個 FIN,用來關閉用戶端到伺服器的資料傳送
- 伺服器-收到這個 FIN,它發回一 個 ACK,确認序号為收到的序号加1 。和 SYN 一樣,一個 FIN 将占用一個序号
- 伺服器-關閉與用戶端的連接配接,發送一個FIN給用戶端
- 用戶端-發回 ACK 封包确認,并将确認序号設定為收到序号加1
- 負責域名解析的 DNS 服務,提供域名到 IP 位址之間的解析服務。 DNS(Domain Name System)服務是和 HTTP 協定一樣位于應用層的協定,它提供域名到 IP 位址之間的解析服務。計算機既可以被賦予 IP 位址,也可以被賦予主機名和域名。使用者通常使用主機名或域名來通路對方的計算機,DNS 協定提供通過域名查找 IP 位址,發送給計算機的是 IP 位址。計算機可通過 DNS 協定的逆向從 IP 位址反查域名。
概括下請求響應的流程:
- 用戶端發起請求,想通路某個主機名或域名;
- DNS 協定對主機名或域名進行解析,得到 IP 位址;
- HTTP 協定将請求封包分割成多個封包段來發送;
- IP 協定通過 IP 位址和 MAC 位址将資料送往對方;
- TCP 協定使用三次握手政策確定資料發送成功,按序号以原來的順序重組請求封包;
- 服務端獲得請求封包,進行處理,處理結果同樣使用 TCP / IP 協定進行回傳。
URI 和 URL
URL(Uniform Resource Locator,統一資源定位符),使用 Web 浏覽器等通路 Web 頁面時需要輸入的網頁位址,比如
https://www.google.com/。URI 是 Uniform Resource Identifier 的縮寫,這三個單詞分别表示:
- Uniform,規定統一的格式可友善處理多種不同類型的資源,而不用根據上下文環境來識别資源指定的通路方式。另外,加入新增的協定方案(如 http: 或 ftp:)也更容易;
- Resource,資源的定義是“可辨別的任何東西”。除了文檔檔案、圖像或服務(例如當天的天氣預報)等能夠差別于其他類型的,全都可作為資源。另外,資源不僅可以是單一的,也可以是多數的集合體;
- Identifier,表示可辨別的對象。也稱為辨別符;
綜上所述,URI 就是由某個協定方案表示的資源的定位辨別符。協定方案是指通路資源所使用的協定類型名稱。采用 HTTP 協定時,協定方案就是 http。URI 用字元串辨別某一網際網路資源,而 URL表示資源的地點(網際網路上所處的位置),可見 URL是 URI 的子集。
絕對URI 格式
以 “
http://user:[email protected]:80/dir/index.html?uid=1#ch1” 為例:
- "http://" ,協定方案名。使用 http: 或 https: 等協定方案名擷取通路資源時要指定協定類型。不區分字母大小寫,最後附一個冒号(:)。也可使用 data: 或 javascript: 這類指定資料或腳本程式的方案名;
- "user:pass" ,登入資訊(認證)。指定使用者名和密碼作為從伺服器端擷取資源時必要的登入資訊(身份認證),此項是可選項;
- "www.example.jp" ,伺服器位址。使用絕對 URI 必須指定待通路的伺服器位址。位址可以是類似 hackr.jp 這種 DNS 可解析的名稱,或是 192.168.1.1 這類 IPv4 位址名,還可以是 [0:0:0:0:0:0:0:1] 這樣用方括号括起來的 IPv6 位址名;
- "80",伺服器端口号。指定伺服器連接配接的網絡端口号。此項也是可選項,若使用者省略則自動使用預設端口号;
- "dir/index.html",帶層次的檔案路徑。指定伺服器上的檔案路徑來定位特指的資源。這與 UNIX 系統的檔案目錄結構相似;
- "uid=1",查詢字元串。針對已指定的檔案路徑内的資源,可以使用查詢字元串傳入任意參數,此項可選;
- "ch1",使用片段辨別符通常可标記出已擷取資源中的子資源(文檔内的某個位置)。但在 RFC 中并沒有明确規定其使用方法,該項也為可選項。
常見的面試題
TCP三向交握
為什麼要三次握手?
三次握手的目的是建立可靠的通信信道,說到通訊,簡單來說就是資料的發送與接收,而三次握手最主要的目的就是雙方确認自己與對方的發送與接收是正常的。
- 第一次握手:Client 什麼都不能确認;Server 确認了對方發送正常
- 第二次握手:Client 确認了:自己發送、接收正常,對方發送、接收正常;Server 确認了:自己接收正常,對方發送正常
- 第三次握手:Client 确認了:自己發送、接收正常,對方發送、接收正常;Server 确認了:自己發送、接收正常,對方發送、接收正常
是以三次握手就能确認雙發收發功能都正常,缺一不可。、
為什麼要傳回 SYN?
接收端傳回發送端所發送的 SYN 是為了告訴發送端,我接收到的資訊确實就是你所發送的信号了。
SYN 是 TCP/IP 建立連接配接時使用的握手信号。在客戶機和伺服器之間建立正常的 TCP 網絡連接配接時,客戶機首先發出一個 SYN 消息,伺服器使用 SYN-ACK 應答表示接收到了這個消息,最後客戶機再以 ACK(Acknowledgement[漢譯:确認字元 ,在資料通信傳輸中,接收站發給發送站的一種傳輸控制字元。它表示确認發來的資料已經接受無誤。 ])消息響應。這樣在客戶機和伺服器之間才能建立起可靠的TCP連接配接,資料才可以在客戶機和伺服器之間傳遞。
為什麼TCP用戶端最後還要發送一次确認呢?
一句話,主要防止已經失效的連接配接請求封包突然又傳送到了伺服器,進而産生錯誤。
- 如果使用的是兩次握手建立連接配接,假設有這樣一種場景,用戶端發送了第一個請求連接配接并且沒有丢失,隻是因為在網絡結點中滞留的時間太長了,由于TCP的用戶端遲遲沒有收到确認封包,以為伺服器沒有收到,此時重新向伺服器發送這條封包,此後用戶端和伺服器經過兩次握手完成連接配接,傳輸資料,然後關閉連接配接。此時此前滞留的那一次請求連接配接,網絡通暢了到達了伺服器,這個封包本該是失效的,但是,兩次握手的機制将會讓用戶端和伺服器再次建立連接配接,這将導緻不必要的錯誤和資源的浪費。
- 如果采用的是三次握手,就算是那一次失效的封包傳送過來了,服務端接受到了那條失效封包并且回複了确認封包,但是用戶端不會再次發出确認。由于伺服器收不到确認,就知道用戶端并沒有請求連接配接。
為什麼要四次揮手?
任何一方都可以在資料傳送結束後發出連接配接釋放的通知,待對方确認後進入半關閉狀态。當另一方也沒有資料再發送的時候,則發出連接配接釋放通知,對方确認後就完全關閉了TCP連接配接。
舉個例子:A 和 B 打電話,通話即将結束後,A 說“我沒啥要說的了”,B回答“我知道了”,但是 B 可能還會有要說的話,A 不能要求 B 跟着自己的節奏結束通話,于是 B 可能又巴拉巴拉說了一通,最後 B 說“我說完了”,A 回答“知道了”,這樣通話才算結束。
為什麼用戶端最後還要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允許不同的實作可以設定不同的MSL值。
- 第一,保證用戶端發送的最後一個ACK封包能夠到達伺服器,因為這個ACK封包可能丢失,站在伺服器的角度看來,我已經發送了FIN+ACK封包請求斷開了,用戶端還沒有給我回應,應該是我發送的請求斷開封包它沒有收到,于是伺服器又會重新發送一次,而用戶端就能在這個2MSL時間段内收到這個重傳的封包,接着給出回應封包,并且會重新開機2MSL計時器。
- 第二,防止類似與“三次握手”中提到了的“已經失效的連接配接請求封包段”出現在本連接配接中。用戶端發送完最後一個确認封包後,在這個2MSL時間中,就可以使本連接配接持續的時間内所産生的所有封包段都從網絡中消失。這樣新的連接配接中不會出現舊連接配接的請求封包。
為什麼建立連接配接是三次握手,關閉連接配接确是四次揮手呢?
建立連接配接的時候, 伺服器在LISTEN狀态下,收到建立連接配接請求的SYN封包後,把ACK和SYN放在一個封包裡發送給用戶端。
而關閉連接配接時,伺服器收到對方的FIN封包時,僅僅表示對方不再發送資料了但是還能接收資料,而自己也未必全部資料都發送給對方了,是以己方可以立即關閉,也可以發送一些資料給對方後,再發送FIN封包給對方來表示同意現在關閉連接配接,是以,己方ACK和FIN一般都會分開發送,進而導緻多了一次。