C++面試題整理之計算機網絡(一)

# 計算機網絡

> * [OSI七層協議及TCP/IP四層協議](#OSI七層協議及TCPIP四層協議)
> * [通信交互方式](#通信交互方式)
> * [MAC地址和IP地址](#MAC地址和IP地址)
> * [ARP協議的作用](#ARP協議的作用)
> * [ping發生了什麼](#ping發生了什麼)
> * [traceroute發生了什麼](#traceroute發生了什麼)
> * [TCP/UDP的區別和應用場景](#TCPUDP的區別和應用場景)
> * [擁塞控制和流量控制的區別](#擁塞控制和流量控制的區別)
> * [TCP滑動窗口實現流量控制](#TCP滑動窗口實現流量控制)
> * [TCP超時重傳](#TCP超時重傳)
> * [TCP擁塞機制](#TCP擁塞機制)
> * [TCP三次握手及三次緣由](#TCP三次握手及三次緣由)
> * [TCP四次揮手及四次緣由](#TCP四次揮手及四次緣由)
> * [TIME-WAIT狀態及2MSL時間](#TIME-WAIT狀態及2MSL時間)
> * [域名系統DNS](#域名系統DNS)
> * [統一資源定位符URL](#統一資源定位符URL)
> * [描述一下HTTP協議](#描述一下HTTP協議)
> * [HTTP2.0](#HTTP2)
> * [HTTP持久連接與管線化](#HTTP持久連接與管線化)
> * [HTTP協議請求報文具體信息](#HTTP協議請求報文具體信息)
> * [GET和POST的區別](#GET和POST的區別)
> * [HTTP協議響應報文具體信息](#HTTP協議響應報文具體信息)
> * [HTTP狀態碼](#HTTP狀態碼)
> * [瀏覽器鍵入URL後的訪問流程](#瀏覽器鍵入URL後的訪問流程)
> * [IP/TCP/UDP分片](#IPTCPUDP分片)
> * [對稱密鑰和公鑰密碼體制](#對稱密鑰和公鑰密碼體制)
> * [數字簽名和數字證書](#數字簽名和數字證書)
> * [HTTP和HTTPS的區別](#HTTP和HTTPS的區別)
> * [運輸層安全協議及SSL工作過程](#運輸層安全協議及SSL工作過程)
> * [HTTPS必須在每次請求中都要先在SSL/TLS層進行握手傳輸密鑰嗎?](#HTTPS必須在每次請求中都要先在SSL/TLS層進行握手傳輸密鑰嗎)
> * [cookie和session](#cookie和session)
> * [瀏覽器關閉後,session就銷燬了嗎](#瀏覽器關閉後session就銷燬了嗎)

## OSI七層協議及TCP/IP四層協議

* 七層協議:物、數、網、傳、會、表、應
  * 物理層  RJ45     
  * 數據鏈路層  PPP,IEEE 802.3/802.2
  * 網絡層 IP,ARP 
  * 傳輸層 TCP,UDP
  * 會話層   
  * 表示層 TIFF,GIF,JPEG
  * 應用層 DNS,HTTP,FTP      

* 四層協議:數據鏈路層(物理層,數據鏈路層),網絡層(網絡層),傳輸層(傳輸層),應用層(會話層,表示層,應用層)
  * 數據鏈路層: PPP**MAC不屬於協議,只是一個地址**
  * 網絡層:IP、ARP、ICMP
  * 傳輸層:TCP、UDP
  * 應用層:DNS、HTTP、FTP

## 通信交互方式

* 單工通信
  * 只能有一個方向的通信沒有反方向的交互 
* 半雙工通信
  * 雙方可以發送消息,但不能同時發送。可以交替進行一方發送、另一方接收 
* 全雙工通信
  * 通信的雙方可以同時發送和接收信息

## MAC地址和IP地址

* MAC地址又叫硬件地址或物理地址,它不是地址位置,實際上是適配器地址,每一臺計算機中固化在適配器的ROM中的地址,作用是用來定義網絡設備的位置
* IP地址是IP協議提供的一種統一的地址格式,爲互聯網上的每一個網絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差異
* 兩者的區別
  * 物理地址是數據鏈路層和物理層使用的地址,放在MAC幀的首部
  * IP地址是網絡層和以上各層使用的地址,放在IP數據報的首部

## ARP協議的作用

網絡層使用的是IP地址,數據鏈路層使用的是硬件地址。
ARP協議的用途是爲了從網絡層使用的IP地址,解析出數據鏈路層使用的硬件地址。

* 在主機ARP高速緩存中存放一個從IP地址到硬件地址的映射表
* 當需要解析時,先去arp緩存表(存着ip-mac對應關係)去查找目標ip的mac地址
* 如果查到了,將目標ip的mac地址封裝到鏈路層數據報
* 如果緩存中沒有找到,會發起一個廣播:who is ip XXX tell ip XXX,所有收到的廣播的機器看這個ip是不是自己的,如果是自己的,則以單播的形式將自己的mac地址回覆給請求的機器 

## [ping發生了什麼](https://blog.csdn.net/fd8559350/article/details/52135571)

ping主要是爲了測試兩臺主機之間的連通性,通過應用層直接使用網絡層ICMP,沒有通過運輸層TCP和UDP,是通過發送ICMP報文回顯請求實現。

> * A主機構建一個ICMP格式的數據包,通過ICMP協議把該數據包和B主機的IP地址一起交給IP協議;
> * IP層構建一個數據包(A主機的IP地址+控制信息+B主機的IP地址),獲得B主機的MAC地址,以便構建一個數據幀(IP協議會根據B主機的IP地址和自己的子網掩碼判斷是不是屬於同一層網絡,如果是屬於同一層網絡的話,就會獲得B主機的MAC地址,如果以前兩機有過通信,在A機的ARP緩存表應該有B機IP與其MAC的映射關係,如果沒有,就發一個ARP請求廣播,得到B機的MAC)
> * 主機B接受到主機A的發過來的數據幀以後,先檢查該幀中包含的B的IP地址,並和本地的物理地址進行比對,如果符合的話,就接受,否則,就拋棄。同樣,需要將該數據幀交由自己的IP層協議,IP層檢查以後,再交由ICMP協議,構建一個ICMP的應答包,發送給主機A。

## traceroute發生了什麼

traceroute用來跟蹤一個分組從源點到終點的路徑,及到達其中每一個路由器的往返時間

* 通過發送UDP報文,設置目的端口爲一個不可能的值
* 將IP首部中的TTL分別設置從1到N,每次逐個增加
* 每次設置TTL後,重新發送數據報,路由器接收到數據報後,將TTL減1,若當前的路由器接收到數據報,發現TTL爲1時,會將TTL減1變爲0,然後丟棄數據報,發送ICMP時間超過報文
* 如果最後一個數據報剛剛達到主機,數據報的TTL是1,此時主機不把TTL減1
* 因IP數據報中封裝的是無法交付的UDP數據報,此時目的主機向源主機發送ICMP終點不可達差錯報文,表示達到目的主機

## TCP/UDP的區別和應用場景

##區別
TCP,全稱:傳輸控制協議,面向連接的安全的流式傳輸協議
UDP,全稱:用戶數據報協議,面向無連接的不安全的報式傳輸協議

* 連接
  * TCP是面向連接的傳輸層協議,即傳輸數據之前必須先建立好連接。
  * UDP無連接。

* 服務對象
  * TCP是點對點的兩點間服務,即一條TCP連接只能有兩個端點
  * UDP支持一對一,一對多,多對一,多對多的交互通信。

* 可靠性
  * TCP是可靠交付:無差錯,不丟失,不重複,按序到達。
  * UDP是盡最大努力交付,不保證可靠交付。

* 擁塞控制,流量控制
  * TCP有擁塞控制和流量控制保證數據傳輸的安全性。
  * UDP沒有擁塞控制,網絡擁塞不會影響源主機的發送效率。

* 報文長度
  * TCP是動態報文長度,即TCP報文長度是根據接收方的窗口大小和當前網絡擁塞情況決定的,流式傳輸
  * UDP面向報文,不合並,不拆分,保留上面(應用層)傳下來報文的邊界,直接傳輸報文。

* 首部開銷
  * TCP首部開銷大,首部20個字節。
  * UDP首部開銷小,8字節。(源端口,目的端口,UDP數據報長度,檢驗和,每個字段兩個字節) 

## 應用場景

* 要求通信數據完整性,則應該選用TCP協議(如文件傳輸、重要狀態的更新,登錄數據傳輸等)
* 要求通信實時性,使用 UDP 協議(如視頻傳輸,通話,屏幕共享軟件)

## TCP保證可靠性

(1)序列號、**確認應答、超時重傳**

數據到達接收方,接收方需要發出一個確認應答,表示已經收到該數據段,並且確認序號會說明了它下一次需要接收的數據序列號。如果發送發遲遲未收到確認應答,那麼可能是發送的數據丟失,也可能是確認應答丟失,這時發送方在等待一定時間後會進行重傳。這個時間一般是2*RTT(報文段往返時間)+一個偏差值。

(2)**窗口控制與高速重發控制/快速重傳**(重複確認應答)

TCP會利用窗口控制來提高傳輸速度,意思是在一個窗口大小內,不用一定要等到應答才能發送下一段數據,窗口大小就是無需等待確認而可以繼續發送數據的最大值。如果不使用窗口控制,每一個沒收到確認應答的數據都要重發。

使用窗口控制,如果數據段1001-2000丟失,後面數據每次傳輸,確認應答都會不停地發送序號爲1001的應答,表示我要接收1001開始的數據,發送端**如果收到3次相同應答,就會立刻進行重發**;但還有種情況有可能是數據都收到了,但是有的應答丟失了,這種情況不會進行重發,因爲發送端知道,如果是數據段丟失,接收端不會放過它的,會瘋狂向它提醒......

(3)**擁塞控制**

如果把窗口定的很大,發送端連續發送大量的數據,可能會造成網絡的擁堵(大家都在用網,你在這狂發,吞吐量就那麼大,當然會堵),甚至造成網絡的癱瘓。所以TCP在爲了防止這種情況而進行了擁塞控制。

**慢啓動**:定義**擁塞窗口**,一開始將該窗口大小設爲1,之後每次收到確認應答(經過一個rtt),將擁塞窗口大小*2。

**擁塞避免**:設置慢啓動閾值,一般開始都設爲65536。擁塞避免是指當擁塞窗口大小達到這個閾值,擁塞窗口的值不再指數上升,而是加法增加(每次確認應答/每個rtt,擁塞窗口大小+1),以此來避免擁塞。

**將報文段的超時重傳看做擁塞**,則一旦發生超時重傳,我們需要先將閾值設爲當前窗口大小的一半,並且將窗口大小設爲初值1,然後重新進入慢啓動過程。

快速重傳:在遇到**3次重複確認應答**(高速重發控制)時,代表收到了3個報文段,但是這之前的1個段丟失了,便對它進行立即重傳。

然後,先將閾值設爲當前窗口大小的一半,然後將擁塞窗口大小設爲慢啓動閾值+3的大小。

這樣可以達到:在TCP通信時,網絡吞吐量呈現逐漸的上升,並且隨着擁堵來降低吞吐量,再進入慢慢上升的過程,網絡不會輕易的發生癱瘓。

## 擁塞控制和流量控制的區別

* 擁塞控制是防止過多的數據注入到網絡中,可以使網絡中的路由器或鏈路不致過載,是一個全局性的過程。 
* 流量控制是點對點通信量的控制,是一個端到端的問題,主要就是抑制發送端發送數據的速率,以便接收端來得及接收

## [TCP滑動窗口實現流量控制](https://blog.csdn.net/dangzhangjing97/article/details/81008836)

* 流量控制是讓發送方的發送速率不要太快,要讓接收方來得及接收,實現對發送方的流量控制.
* 滑動窗口出現的原因:在確認應答策略中,對每一個發送的數據段,都要給一個ACK確認應答,收到ACK後再發送下一個數據段,這樣做有一個比較大的缺點,就是性能比較差,尤其是數據往返的時間長的時候
* 滑動窗口以字節爲單位,而不是報文

## TCP超時重傳

* 保證了數據的可靠傳輸,對於一些出錯,丟包等問題TCP設計了超時與重傳機制。
* 基本原理:在發送一個數據之後,就開啓一個定時器,並設置RTO,若是在這個時間內沒有收到發送數據的ACK確認報文,則對該報文進行重傳,在達到一定次數還沒有成功時放棄併發送一個復位信號。 
* 不同的網絡情況不一樣,不可能設置一樣的RTO(超時重傳時間),實際中RTO是根據網絡中的RTT(報文段往返時間)來自適應調整的

## [TCP擁塞機制](https://blog.csdn.net/shuxnhs/article/details/80644531)

* 擁塞的標誌
  * 超時重傳
  * 3次重複的ACK

慢啓動,擁塞避免,快恢復,快重傳

## ACK SYN FIN解釋及是否消耗序列號

* ACK 確認標誌位,ACK可以攜帶數據,若不攜帶,則不消耗序列號
* SYN 同步標誌位,SYN不能攜帶數據,必須消耗一個序列號
* FIN 終止標誌位,FIN可以攜帶數據,必須消耗一個序列號

## TCP/IP數據鏈路層的交互過程

數據鏈層用mac地址作爲通信目標,數據包到達網絡層準備往數據鏈層發送的時候,首先會去自己的**arp緩存表**(存着ip-mac對應關係)去**查找該目標ip的mac地址**,如果查到了,就將目標ip的mac地址封裝到鏈路層數據包的包頭。如果緩存中沒有找到,會**發起一個廣播**:who is ip XXX tell ip XXX,**所有收到的廣播的機器看這個ip是不是自己的**,如果是自己的,則**將自己的mac地址回覆給請求的機器**。

## TCP三次握手及三次緣由

* TCP的三次握手過程如下:

  C-> SYN -> S

  S->SYN/ACK->C

  C->ACK->S

* 爲什麼TCP三次握手,不能兩次或者四次嗎?**

  *  三次握手是爲了防止,客戶端的請求報文在網絡滯留,客戶端超時重傳了請求報文,服務端建立連接,傳輸數據,釋放連接之後,服務器又收到了客戶端滯留的請求報文,建立連接一直等待客戶端發送數據。
  *  服務器對客戶端的請求進行迴應(第二次握手)後,就會理所當然的認爲連接已建立,而如果客戶端並沒有收到服務器的迴應呢?此時,客戶端仍認爲連接未建立,服務器會對已建立的連接保存必要的資源,如果大量的這種情況,服務器會崩潰。 
  *  服務器端給客戶端發送同步及確認報文時可以合併,四次會浪費時間

## TCP四次揮手及四次緣由

四次報文中服務器端發送給客戶端的請求關閉連接報文FIN和ACK也是合併的,相對於三次來說,只是前面多了一次ACK的確認。

- TCP的四次揮手過程如下:

  C->FIN->S

  S->ACK->C

  S->FIN->C

  C->ACK->S

* **爲什麼TCP四次揮手,不能三次嗎?**
  * 當客戶端確認發送完數據且知道服務器已經接收完了,想要關閉發送數據口(當然確認信號還是可以發),就會發FIN給服務器。
  * 服務器收到客戶端發送的FIN,表示收到了,就會發送ACK回覆。
  * 但這時候**服務器可能還在發送數據,沒有想要關閉數據口的意思,所以服務器的FIN與ACK不是同時發送的**,而是等到服務器數據發送完了,纔會發送FIN給客戶端。
  * 客戶端收到服務器發來的FIN,知道服務器的數據也發送完了,回覆ACK, 客戶端等待2MSL以後,沒有收到服務器傳來的任何消息,知道服務器已經收到自己的ACK了,客戶端就關閉鏈接,服務器也關閉鏈接(服務器比客戶端早關閉)。 


## TIME-WAIT狀態及2MSL時間

* 四次揮手期間,客戶端和服務器端都可主動關閉連接,誰主動關閉,誰將進入TIME_WAIT狀態
* MSL是最長報文壽命,一般爲2分鐘,2MSL即4分鐘
* 爲什麼TIME-WAIT狀態必須等待2MSL時間?
  * **保證最後一次揮手報文能到B,能進行超時重傳。**若B收不到A的ACK報文,則B會超時重傳FIN+ACK,A會在2MSL時間內收到重傳報文段,然後發送ACK,重新啓動2MSL計時器
  * 2MSL後,本次連接的所有報文都會消失,不會影響下一次連接。 

## 域名系統DNS

用於將域名轉換爲IP地址。
DNS解析過程有兩種,分別是遞歸查詢和迭代查詢。

* 遞歸查詢
  * 若主機詢問的本地域名服務器不知道被查詢域名的IP地址,本地域名服務器以DNS客戶身份,向其他根域名服務器繼續發出查詢請求報文(代替該主機繼續查詢),而不是該主機自己進行下一步查詢 
* 迭代查詢
  * 當根域名服務器收到本地域名服務器發出的迭代查詢請求報文時,要麼給出IP地址,要麼告訴本地域名服務器,應該向哪一個域名服務器進行查詢,然後本地域名服務器進行後續查詢

## 統一資源定位符URL

統一資源定位符URL,用來表示從互聯網上得到的資源位置。

* 一般由四個部分組成
  * <協議>://<主機>:<端口>/<路徑>
  * 主機一般爲域名,需要通過DNS系統解析出IP

* 使用HTTP的URL
  * http://<主機>:<端口>/<路徑>

## [HTTP,HTTPS,HTTP2的長連接和短連接的區別](https://www.cnblogs.com/heluan/p/8620312.html)

### HTTP(端口是80)

- **簡單快速**:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有 GET、HEAD、POST 等等。每種方法規定了客戶與服務器聯繫的類型不同。由於 HTTP 協議簡單,使得 HTTP 服務器的程序規模小,因而通信速度很快。

- **數據格式靈活**:HTTP 允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type 加以標記。

- **無連接**:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。

- **無狀態**:HTTP 協議是無狀態協議。無狀態,是指協議對於事務處理沒有記憶能力。**無狀態意味着如果後續處理需要前面的信息,則它必須重傳**,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

### HTTPS (端口是443)

實際就是在 TCP 層與 HTTP 層之間加入了 SSL/TLS 來爲上層的安全保駕護航,主要用到對稱加密、非對稱加密、證書,等技術進行客戶端與服務器的數據加密傳輸,最終達到保證整個通信的安全性。

**HTTPS實現的過程**

- **建立連接獲取證書**

  SSL 客戶端通過 TCP 和服務器建立連接之後(443 端口),並且在一般的 tcp 連接協商(握 手)過程中請求證書。即客戶端發出一個消息給服務器,這個消息裏面包含了自己可實現的算法列表和其它一些需要的消息,SSL 的服務器端會迴應一個數據包,這裏面確定了這次通信所需要的算法,然後服務器向客戶端返回證書。(證書裏面包含了服務器信息:域名,申請證書 的公司,公共祕鑰)。

- **證書驗證**

  Client 在收到服務器返回的證書後,判斷簽發這個證書的公共簽發機構,並使用這個機構的公 共祕鑰確認簽名是否有效,客戶端還會確保證書中列出的域名就是它正在連接的域名。

- **數據加密和傳輸**

  如果確認證書有效,那麼生成對稱祕鑰並使用服務器的公共祕鑰進行加密。然後發送給服務器,服務器使用它的私鑰對它進行解密,這樣兩臺計算機可以開始進行對稱加密進行通信。

**HTTP 和 HTTPS 的區別**
端口不同:HTTP 與 HTTPS 使用不同的連接方式,用的端口也不一樣,前者是 80,後者是 443。

資源消耗:和 HTTP 通信相比,HTTPS 通信會由於加解密處理消耗更多的 CPU 和內存資源。

開銷:HTTPS 通信需要證書,而證書一般需要向認證機構申請免費或者付費購買。

### HTTP2.0

 HTTP2.0和 HTTP1.X 相比的新特性

1. HTTP/2採用二進制格式而非文本格式
2. HTTP/2是完全多路複用的,而非有序並阻塞的——只需一個連接即可實現並行
3. 使用報頭壓縮,HTTP/2降低了開銷
4. HTTP/2讓[服務器](https://www.baidu.com/s?wd=服務器&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd)可以將響應主動“推送”到客戶端緩存中

## [描述一下HTTP協議](https://www.cnblogs.com/ranyonsue/p/5984001.html)

### 概述

* HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web)服務器傳輸超文本到本地瀏覽器的傳送協議。
* HTTP屬於應用層協議,基於TCP/IP通信協議來傳遞數據

### 特點

* 靈活
  * HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
* 無連接
  * 無連接的含義是通信雙方在交換HTTP報文之前不需要建立HTTP連接
* 無狀態
  * 無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時應答較快。
* 支持B/S和C/S模式
* 默認端口80
* 基於TCP協議 

### HTTP工作原理

HTTP協議定義Web客戶端如何從Web服務器請求Web頁面,以及服務器如何把Web頁面傳送給客戶端。

* 客戶端向服務器發送一個請求報文,請求報文包含請求的方法、URL、協議版本、請求頭部和請求數據。
* 服務器以一個狀態行作爲響應,響應的內容包括協議的版本、成功或者錯誤代碼、服務器信息、響應頭部和響應數據。

**HTTP 請求/響應的步驟**

> * **客戶端連接到Web服務器**
>   一個HTTP客戶端,通常是瀏覽器,與Web服務器的HTTP端口(默認爲80)建立一個TCP套接字連接。例如,http://www.oakcms.cn。
> * **發送HTTP請求**
>   通過TCP套接字,客戶端向Web服務器發送一個文本的請求報文,一個請求報文由請求行、請求頭部、空行和請求數據4部分組成。
> * **服務器接受請求並返回HTTP響應**
>   Web服務器解析請求,定位請求資源。服務器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應數據4部分組成。
> * **釋放連接TCP連接**
>   若connection 模式爲close,則服務器主動關閉TCP連接,客戶端被動關閉連接,釋放TCP連接;若connection 模式爲keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求;
> * **客戶端瀏覽器解析HTML內容**
>   客戶端瀏覽器首先解析狀態行,查看錶明請求是否成功的狀態代碼。然後解析每一個響應頭,響應頭告知以下爲若干字節的HTML文檔和文檔的字符集。客戶端瀏覽器讀取響應數據HTML,根據HTML的語法對其進行格式化,並在瀏覽器窗口中顯示。

## [HTTP2](https://www.cnblogs.com/heluan/p/8620312.html)

* 新的二進制格式(Binary Format)
  * HTTP1.x的解析是基於文本。基於文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合。基於這種考慮HTTP2.0的協議解析決定採用二進制格式,實現方便且健壯。
* 多路複用(MultiPlexing)
  * 即連接共享,即每一個request都是是用作連接共享機制的。一個request對應一個id,這樣一個連接上可以有多個request,每個連接的request可以隨機的混雜在一起,接收方可以根據request的 id將request再歸屬到各自不同的服務端請求裏面。
  * pipelining在接收response返回時,必須依順序接收,如果前一個請求遇到了阻塞,後面的請求即使已經處理完畢了,仍然需要等待阻塞的請求處理完畢。這種情況就如圖中第三種,第一個請求阻塞後,後面的請求都需要等待,這也就是隊頭阻塞
* header壓縮
  * 對前面提到過HTTP1.x的header帶有大量信息,而且每次都要重複發送,HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重複header的傳輸,又減小了需要傳輸的大小
* 服務端推送
  * 我的網頁有一個sytle.css的請求,在客戶端收到sytle.css數據的同時,服務端會將sytle.js的文件推送給客戶端,當客戶端再次嘗試獲取sytle.js時就可以直接從緩存中獲取到,不用再發請求了

## HTTP持久連接與管線化

HTTP 協議的初始版本中, **每進行一次 HTTP 通信就要斷開一次 TCP連接**。  爲解決上述 TCP 連接的問題, HTTP/1.1 和一部分的HTTP/1.0 想出了**持久連接**(HTTP Persistent Connections, 也稱爲 HTTP keep-alive 或HTTP connection reuse) 的方法。 持久連接的特點是, 只要任意一端沒有明確提出斷開連接, 則**保持 TCP 連接狀態**。  

持久連接的好處在於減少了 TCP 連接的重複建立和斷開所造成的額外開銷, 減輕了服務器端的負載。 另外, 減少開銷的那部分時間, 使HTTP 請求和響應能夠更早地結束, 這樣 Web 頁面的顯示速度也就相應提高了。  

* 請求一個萬維網文檔的時間
  * 當建立TCP連接的三次握手前兩次完成後,即經過一個RTT時間,萬維網客戶就把HTTP請求報文,作爲建立TCP連接的三次握手中的第三次的數據,發送給萬維網服務器,服務器收到HTTP請求後,把請求的文檔作爲響應報文返回給客戶。
  * 文檔傳輸時間+2*RTT

* HTTP1.0非持久連接的缺點
  * 每請求一個文檔,需要兩倍RTT的開銷。服務器主動關閉TCP連接,客戶端被動關閉連接,釋放TCP連接,然後重新建立連接發出請求

* HTTP1.1持久連接
  * 萬維網服務器在發送響應後仍然在一段時間內保持這段連接,可以使得同一用戶繼續在該連接上傳送後續請求和響應報文

* 持久連接的兩種工作方式
  * 非管線化
    * 發送請求後需等待並收到迴應,才能發送下一個請求 
  * 管線化
    * 不用等待響應,直接發送下一個請求,但接收的時候必須按照順序接收,如果有一個請求阻塞,則接收會全部阻塞


## HTTP協議請求報文具體信息

HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成

* **GET**

  ```C++
  GET /562f25980001b1b106000338.jpg HTTP/1.1
  Host:img.mukewang.com
  User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64)
  AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
  Accept:image/webp,image/*,*/*;q=0.8
  Referer:http://www.imooc.com/
  Accept-Encoding:gzip, deflate, sdch
  Accept-Language:zh-CN,zh;q=0.8
  空行
  請求數據爲空
  ```

* **POST**

  ```C++
  POST / HTTP1.1
  Host:www.wrox.com
  User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
  Content-Type:application/x-www-form-urlencoded
  Content-Length:40
  Connection: Keep-Alive
  空行
  name=Professional%20Ajax&publisher=Wiley
  ```

> * **請求行**,用來說明請求類型,要訪問的資源以及所使用的HTTP版本.
>   GET說明請求類型爲GET,/562f25980001b1b106000338.jpg(URL)爲要訪問的資源,該行的最後一部分說明使用的是HTTP1.1版本。
> * **請求頭部**,緊接着請求行(即第一行)之後的部分,用來說明服務器要使用的附加信息
>   * HOST,給出請求資源所在服務器的域名.
>   * User-Agent,HTTP客戶端程序的信息,該信息由你發出請求使用的瀏覽器來定義,並且在每個請求中自動發送等
>   * Accept,說明用戶代理可處理的媒體類型
>   * Accept-Encoding,說明用戶代理支持的內容編碼
>   * Accept-Language,說明用戶代理能夠處理的自然語言集
>   * Content-Type,說明實現主體的媒體類型
>   * Content-Length,說明實現主體的大小
>   * Connection,連接管理,可以是Keep-Alive或close
> * **空行**,請求頭部後面的空行是必須的即使第四部分的請求數據爲空,也必須有空行。
> * **請求數據**也叫主體,可以添加任意的其他數據。

## GET和POST區別

```C++
GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
空行
請求數據爲空
```

* 區別
  * **get參數通過url傳遞,post放在request body中**,GET提交的數據會在地址欄中顯示出來,而POST提交,地址欄不會改變
  * **POST的安全性要比GET的安全性高**,一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該用戶的賬號和密碼.
  * **get請求在url中傳遞的參數是有長度限制的,而post沒有**
  * **GET產生一個TCP數據包,POST產生兩個TCP數據包**。 
    *  對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);
    *  對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據) 


## HTTP協議響應報文具體信息

HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。

```C++
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
      <head></head>
      <body>
            <!--body goes here-->
      </body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章