計算機網絡(三)—— 應用層

應用層(HTTP)

1. ISO七層模型中表示層和會話層功能是什麼?
  • 表示層:圖像、視頻編碼解,數據加密。

  • 會話層:建立會話,如session認證、斷點續傳。

2. 會話層、表示層、應用層
  • 數據傳輸基本單位爲報文;

  • 包含的主要協議:FTP(文件傳送協議)、Telnet(遠程登錄協議)、DNS(域名解析協議)、SMTP(郵件傳送協議),POP3協議(郵局協議),HTTP協議(Hyper Text Transfer Protocol)。

DNS協議

  • DNS是域名系統(DomainNameSystem)的縮寫,該系統用於命名組織到域層次結構中的計算機和網絡服務,可以簡單地理解爲將URL轉換爲IP地址。域名是由圓點分開一串單詞或縮寫組成的,每一個域名都對應一個惟一的IP地址,在Internet上域名與IP地址之間是一一對應的,DNS就是進行域名解析的服務器。DNS命名用於Internet等TCP/IP網絡中,通過用戶友好的名稱查找計算機和服務。

NAT協議

  • NAT網絡地址轉換(Network Address Translation)屬接入廣域網(WAN)技術,是一種將私有(本地?保留)地址轉化爲合法IP地址的轉換技術,它被廣泛應用於各種類型Internet接入方式和各種類型的網絡中。原因很簡單,NAT不僅完美地解決了lP地址不足的問題,而且還能夠有效地避免來自網絡外部的攻擊,隱藏並保護網絡內部的計算機。

DHCP協議

  • DHCP動態主機設置協議(Dynamic Host Configuration Protocol)是一個局域網的網絡協議,使用UDP協議工作,主要有兩個用途:給內部網絡或網絡服務供應商自動分配IP地址,給用戶或者內部網絡管理員作爲對所有計算機作中央管理的手段。

HTTP協議

  • HTTP協議工作在應用層,端口號是80。HTTP協議被用於網絡中兩臺計算機間的通信,相比於TCP/IP這些底層協議,HTTP協議更像是高層標記型語言,瀏覽器根據從服務器得到的HTTP響應體中分別得到報文頭,響應頭和信息體(HTML正文等),之後將HTML文件解析並呈現在瀏覽器上。同樣,我們在瀏覽器地址欄輸入網址之後,瀏覽器相當於用戶代理幫助我們組織好報文頭,請求頭和信息體(可選),之後通過網絡發送到服務器,,服務器根據請求的內容準備數據。所以如果想要完全弄明白HTTP協議,你需要寫一個瀏覽器 + 一個Web服務器,一側來生成請求信息,一側生成響應信息。

  • 從網絡分層模型來看,HTTP工作在應用層,其在傳輸層由TCP協議爲其提供服務。所以可以猜到,HTTP請求前,客戶機和服務器之間一定已經通過三次握手建立起連接,其中套接字中服務器一側的端口號爲HTTP周知端口80。在請求和傳輸數據時也是有講究的,通常一個頁面上不只有文本數據,有時會內嵌很多圖片,這時候有兩種選擇可以考慮。
    一種是對每一個文件都建立一個TCP連接,傳送完數據後立馬斷開,通過多次這樣的操作獲取引用的所有數據,但是這樣一個頁面的打開需要建立多次連接,效率會低很多。
    另一種是對於有多個資源的頁面,傳送完一個數據後不立即斷開連接,在同一次連接下多次傳輸數據直至傳完,但這種情況有可能會長時間佔用服務器資源,降低吞吐率。
    上述兩種模式分別是HTTP 1.0和HTTP 1.1版本的默認方式
    ,具體是什麼含義會在後面詳細解釋。

HTTP工作流程

一次完整的HTTP請求事務包含以下四個環節:

  • 建立起客戶機和服務器連接。

  • 建立連接後,客戶機發送一個請求給服務器。

  • 服務器收到請求給予響應信息。

  • 客戶端瀏覽器將返回的內容解析並呈現,斷開連接。

HTTP協議結構

請求報文

對於HTTP請求報文我們可以通過以下兩種方式比較直觀的看到:一是在瀏覽器調試模式下(F12)看請求響應信息,二是通過wireshark或者tcpdump抓包實現。通過前者看到的數據更加清晰直觀,通過後者抓到的數據更真實。但無論是用哪種方式查看,得到的請求報文主題體信息都是相同的,對於請求報文,主要包含以下四個部分,每一行數據必須通過"\r\n"分割,這裏可以理解爲行末標識符。

1. 請求報文
  1. 請求報文頭(只有一行)

    結構:method uri version

  • method

    HTTP的請求方法,一共有9中,但GET和POST佔了99%以上的使用頻次。GET表示向特定資源發起請求,當然也能提交部分數據,不過提交的數據以明文方式出現在URL中。POST通常用於向指定資源提交數據進行處理,提交的數據被包含在請求體中,相對而言比較安全些。

  • uri(統一資源標識符(Uniform Resource Identifier,或URI))用來指代請求的文件,≠URL。

  • version

    HTTP協議的版本,該字段有HTTP/1.0和HTTP/1.1兩種。

  1. 請求頭(多行)

    在HTTP/1.1中,請求頭除了Host都是可選的。包含的頭五花八門,這裏只介紹部分。

  • Host:指定請求資源的主機和端口號。端口號默認80。

  • Connection:值爲keep-alive和close。keep-alive使客戶端到服務器的連接持續有效,不需要每次重連,此功能爲HTTP/1.1預設功能。

  • Accept:瀏覽器可接收的MIME類型。假設爲text/html表示接收服務器回發的數據類型爲text/html,如果服務器無法返回這種類型,返回406錯誤。

  • Cache-control:緩存控制,Public內容可以被任何緩存所緩存,Private內容只能被緩存到私有緩存,non-cache指所有內容都不會被緩存。

  • Cookie:將存儲在本地的Cookie值發送給服務器,實現無狀態的HTTP協議的會話跟蹤。

  • Content-Length:請求消息正文長度。

    另有User-Agent、Accept-Encoding、Accept-Language、Accept-Charset、Content-Type等請求頭這裏不一一羅列。由此可見,請求報文是告知服務器請求的內容,而請求頭是爲了提供服務器一些關於客戶機瀏覽器的基本信息,包括編碼、是否緩存等。

  1. 空行(一行)

  2. 可選消息體(多行)

2 響應報文

響應報文是服務器對請求資源的響應,通過上面提到的方式同樣可以看到,同樣地,數據也是以"\r\n"來分割。

  1. 報文頭(一行)

    結構:version status_code status_message

  • version

    描述所遵循的HTTP版本。

  • status_code

    狀態碼,指明對請求處理的狀態,常見的如下。

    • 200:成功。

    • 302:內容已經移動。

    • 400:請求不能被服務器理解。

    • 403:無權訪問該文件。

    • 404:不能找到請求文件。

    • 500:服務器內部錯誤。

    • 501:服務器不支持請求的方法。

    • 505:服務器不支持請求的版本。

    1xx(臨時響應) 表示臨時響應並需要請求者繼續執行操作的狀態代碼。
    2xx (成功) 表示成功處理了請求的狀態代碼。
    3xx (重定向) 表示要完成請求,需要進一步操作。通常,這些狀態代碼用來重定向。
    4xx(請求錯誤) 這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。
    5xx(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

  • status_message

    顯示和狀態碼等價英文描述。

  1. 響應頭(多行)

    這裏只羅列部分。

  • Date:表示信息發送的時間。

  • Server:Web服務器用來處理請求的軟件信息。

  • Content-Encoding:Web服務器表明了自己用什麼壓縮方法壓縮對象。

  • Content-Length:服務器告知瀏覽器自己響應的對象長度。

  • Content-Type:告知瀏覽器響應對象類型。

  1. 空行(一行)

  2. 信息體(多行)

    實際有效數據,通常是HTML格式的文件,該文件被瀏覽器獲取到之後解析呈現在瀏覽器中。

3.HTTP 協議包括哪些請求?
  • GET:請求讀取由URL所標誌的信息。

  • POST:給服務器添加信息(如註釋)。

  • PUT:在給定的URL下存儲一個文檔。

  • DELETE:刪除給定的URL所標誌的資源。

4. HTTP 中,POST 與 GET 的區別

1)Get是從服務器上獲取數據,Post是向服務器傳送數據。

2)Get是把參數數據隊列加到提交表單的Action屬性所指向的URL中,值和表單內各個字段一一對應,在URL中可以看到。

3)Get傳送的數據量小,不能大於2KB;Post傳送的數據量較大,一般被默認爲不受限制。

4)根據HTTP規範,GET用於信息獲取,而且應該是安全的和冪等的。
I. 所謂 安全的 意味着該操作用於獲取信息而非修改信息。換句話說,GET請求一般不應產生副作用。就是說,它僅僅是獲取資源信息,就像數據庫查詢一樣,不會修改,增加數據,
不會影響資源的狀態。
II. 冪等 的意味着對同一URL的多個請求應該返回同樣的結果(這裏其實不應該說是結果……)。說白了就是,同一個請求,發送一次和發送N次效果是一樣的!

5. HTTP的冪等性

這裏主要以HTTP GET、DELETE、PUT、POST四種方法爲主進行語義和冪等性的介紹。

6. 如何防範 POST 重複提交
  • HTTP POST 操作既不是安全的,也不是冪等的(至少在HTTP規範裏沒有保證)。當我們因爲反覆刷新瀏覽器導致多次提交表單,多次發出同樣的POST請求,導致遠端服務器重複創建出了資源。

  • 所以,對於電商應用來說,第一,對應的後端 WebService 一定要做到冪等性,第二,服務器端收到 POST 請求,在操作成功後必須302跳轉到另外一個頁面,這樣即使用戶刷新頁面,也不會重複提交表單。

7. HTTP 與 HTTPS
  • HTTP(HyperText Transfer Protocol:超文本傳輸協議)是一種用於分佈式、協作式和超媒體信息系統的應用層協議。簡單來說就是一種發佈和接收 HTML 頁面的方法,
    被用於在 Web 瀏覽器和網站服務器之間傳遞信息。HTTP 默認工作在 TCP 協議 80 端口,用戶訪問網站 http:// 打頭的都是標準 HTTP 服務。HTTP 協議以明文方式發送內容,
    不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。

  • HTTPS(Hypertext Transfer Protocol Secure:超文本傳輸安全協議)是一種透過計算機網絡進行安全通信的傳輸協議。HTTPS 經由 HTTP 進行通信,但利用 SSL/TLS 來加密數據包。
    HTTPS 開發的主要目的,是提供對網站服務器的身份認證,保護交換數據的隱私與完整性。HTTPS 默認工作在 TCP 協議443端口。

8. HTTP 與 HTTPS 區別
  • HTTP 明文傳輸,數據都是未加密的,安全性較差,HTTPS(SSL+HTTP) 數據傳輸過程是加密的,安全性較好。

  • 使用 HTTPS 協議需要到 CA(Certificate Authority,數字證書認證機構) 申請證書,一般免費證書較少,因而需要一定費用。證書頒發機構如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。

  • HTTP 頁面響應速度比 HTTPS 快,主要是因爲 HTTP 使用 TCP 三次握手建立連接,客戶端和服務器需要交換 3 個包,而 HTTPS除了 TCP 的三個包,還要加上 ssl 握手需要的 9 個包,
    所以一共是 12 個包。

  • http 和 https 使用的是完全不同的連接方式,用的端口也不一樣,前者是 80,後者是 443。

  • HTTPS 其實就是建構在 SSL/TLS(安全套接層/安全傳輸層協議) 之上的 HTTP 協議,所以, HTTPS 比 HTTP 要更耗費服務器資源。

9. HTTPS 的工作原理
  • 我們都知道 HTTPS 能夠加密信息,以免敏感信息被第三方獲取,所以很多銀行網站或電子郵箱等等安全級別較高的服務都會採用 HTTPS 協議。

    • 客戶端發起 HTTPS 請求
      這個沒什麼好說的,就是用戶在瀏覽器裏輸入一個 https 網址,然後連接到 server 的 443 端口。

    • 服務端的配置

      採用 HTTPS 協議的服務器必須要有一套數字證書,可以自己製作,也可以向組織申請,區別就是自己頒發的證書需要客戶端驗證通過,纔可以繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面(startssl 就是個不錯的選擇,有 1 年的免費服務)。這套證書其實就是一對公鑰和私鑰,如果對公鑰和私鑰不太理解,可以想象成一把鑰匙和一個鎖頭,只是全世界只有你一個人有這把鑰匙,你可以把鎖頭給別人,別人可以用這個鎖把重要的東西鎖起來,然後發給你,因爲只有你一個人有這把鑰匙,所以只有你才能看到被這把鎖鎖起來的東西。

    • 傳送證書

      這個證書其實就是公鑰,只是包含了很多信息,如證書的頒發機構,過期時間等等。

    • 客戶端解析證書

      這部分工作是有客戶端的TLS(安全傳輸層協議)來完成的,首先會驗證公鑰是否有效,比如頒發機構,過期時間等等,如果發現異常,則會彈出一個警告框,提示證書存在問題。如果證書沒有問題,那麼就生成一個隨機值,然後用證書對該隨機值進行加密,就好像上面說的,把隨機值用鎖頭鎖起來,這樣除非有鑰匙,不然看不到被鎖住的內容。

    • 傳送加密信息

      這部分傳送的是用證書加密後的隨機值,目的就是讓服務端得到這個隨機值,以後客戶端和服務端的通信就可以通過這個隨機值來進行加密解密了。

    • 服務段解密信息

      服務端用私鑰解密後,得到了客戶端傳過來的隨機值(私鑰),然後把內容通過該值進行對稱加密,所謂對稱加密就是,將信息和私鑰通過某種算法混合在一起,這樣除非知道私鑰,不然無法獲取內容,而正好客戶端和服務端都知道這個私鑰,所以只要加密算法夠彪悍,私鑰夠複雜,數據就夠安全。

    • 傳輸加密後的信息

      這部分信息是服務段用私鑰加密後的信息,可以在客戶端被還原。

    • 客戶端解密信息

      客戶端用之前生成的私鑰解密服務段傳過來的信息,於是獲取瞭解密後的內容,整個過程第三方即使監聽到了數據,也束手無策。

10. HTTP1.0 與 HTTP1.1的區別
  • HTTP 1.1支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理

    • HTTP 1.0規定瀏覽器與服務器只保持短暫的連接,瀏覽器的每次請求都需要與服務器建立一個TCP連接,服務器完成請求處理後立即斷開TCP連接,服務器不跟蹤每個客戶也不記錄過去的請求。

    • HTTP 1.1則支持持久連接Persistent Connection, 並且默認使用persistent connection. 在同一個tcp的連接中可以傳送多個HTTP請求和響應. 多個請求和響應可以重疊,多個請求和響應可以同時進行. 更加多的請求頭和響應頭(比如HTTP1.0沒有host的字段).

      • 在HTTP 1.0時的會話方式:
        1. 建立連接
        2. 發出請求信息
        3. 回送響應信息
        4. 關掉連接
    • HTTP 1.1的持續連接,也需要增加新的請求頭來幫助實現,例如,Connection請求頭的值爲Keep-Alive時,客戶端通知服務器返回本次請求結果後保持連接;
      Connection請求頭的值爲close時,客戶端通知服務器返回本次請求結果後關閉連接。HTTP 1.1還提供了與身份認證、狀態管理和Cache緩存等機制相關的請求頭和響應頭。

    • 請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲。例如:一個包含有許多圖像的網頁文件的多個請求和應答可以在一個連接中傳輸,但每個單獨的網頁文件的請求和應答仍然需要使用各自的連接。 HTTP 1.1還允許客戶端不用等待上一次請求結果返回,就可以發出下一次請求,但服務器端必須按照接收到客戶端請求的先後順序依次回送響應結果,以保證客戶端能夠區分出每次請求的響應內容。

  • HTTP 1.1增加host字段

    • 在HTTP1.0中認爲每臺服務器都綁定一個唯一的IP地址,因此,請求消息中的URL並沒有傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一臺物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。

    • HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。此外,服務器應該接受以絕對路徑標記的資源請求。

  • 100(Continue) Status(節約帶寬)

    • HTTP/1.1加入了一個新的狀態碼100(Continue)。客戶端事先發送一個只帶頭域的請求,如果服務器因爲權限拒絕了請求,就回送響應碼401(Unauthorized);
      如果服務器接收此請求就回送響應碼100,客戶端就可以繼續發送帶實體的完整請求了。100 (Continue) 狀態代碼的使用,允許客戶端在發request消息body之前先用request header試探一下server,看server要不要接收request body,再決定要不要發request body。
  • HTTP/1.1中引入了Chunked transfer-coding來解決上面這個問題,發送方將消息分割成若干個任意大小的數據塊,每個數據塊在發送時都會附上塊的長度,最後用一個零長度的塊作爲消息結束的標誌。這種方法允許發送方只緩衝消息的一個片段,避免緩衝整個消息帶來的過載。

  • HTTP/1.1在1.0的基礎上加入了一些cache的新特性,當緩存對象的Age超過Expire時變爲stale對象,cache不需要直接拋棄stale對象,而是與源服務器進行重新激活(revalidation)。

11. URI與URL區別

很多人會混淆這兩個名詞。

  • URL:(Uniform/Universal Resource Locator 的縮寫,統一資源定位符)。

  • URI:(Uniform Resource Identifier 的縮寫,統一資源標識符)(代表一種標準)。

關係:

  • URI 屬於 URL 更高層次的抽象,一種字符串文本標準。就是說,URI 屬於父類,而 URL 屬於 URI 的子類。URL 是 URI 的一個子集。

  • 二者的區別在於,URI 表示請求服務器的路徑,定義這麼一個資源。而 URL 同時說明要如何訪問這個資源(http://)。

CGI(通用網關接口)與環境變量

  • CGI程序

    • CGI是外部應用程序(CGI程序)與WEB服務器之間的接口標準,是在CGI程序和Web服務器之間傳遞信息的過程。

    • 服務器爲客戶端提供動態服務首先需要解決的是得到用戶提供的參數再根據參數信息返回。爲了和客戶端進行交互,服務器需要先創建子進程,之後子進程執行相應的程序去爲客戶服務。CGI正是幫助我們解決參數獲取、輸出結果的。動態內容獲取其實請求報文的頭部和請求靜態數據時完全相同,但請求的資源從靜態的HTML文件變成了後臺程序。服務器收到請求後fork()一個子進程,子進程執行請求的程序,這樣的程序稱爲CGI程序(Python、Perl、C++等均可)。通常在服務器中我們會預留一個單獨的目錄(cgi-bin)用來存放所有的CGI程序,請求報文頭部中請求資源的前綴都是/cgi-bin,之後加上所請求調用的CGI程序即可。所以上述流程就是:客戶端請求程序 -> 服務器fork()子進程 -> 執行被請求程序。接下來需要解決的問題就是如何獲取客戶端發送過來的參數和輸出信息怎麼傳遞迴客戶端。

  • 環境變量

    對CGI程序來說,CGI環境變量在創建時被初始化,結束時被銷燬。當CGI程序被HTTP服務器調用時,因爲是被服務器fork()出來的子進程,所以其繼承了其父進程的環境變量,這些環境變量包含了很多基本信息,請求頭中和響應頭中列出的內容(比如用戶Cookie、客戶機主機名、客戶機IP地址、瀏覽器信息等),CGI程序所需要的參數也在其中。

    • GET方法下參數獲取

      服務器把接收到的參數數據編碼到環境變量QUERY_STRING中,在請求時只需要直接把參數寫到URL最後即可,比如"http:127.0.0.1:80/cgi-bin/test?a=1&b=2&c=3",表示請求cgi-bin目錄下test程序,’?‘之後部分爲參數,多個參數用’&'分割開。服務器接收到請求後環境變量QUERY_STRING的值即爲a=1&b=2&c=3。

      在CGI程序中獲取環境變量值的方法是:getenv(),比如我們需要得到上述QUERY_STRING的值,只需要下面這行語句就可以了。

        char *value = getenv("QUERY_STRING");
      

      之後對獲得的字符串處理一下提取出每個參數信息即可。

    • POST方法下參數獲取

      POST方法下,CGI可以直接從服務器標準輸入獲取數據,不過要先從CONTENT_LENGTH這個環境變量中得到POST參數長度,再獲取對應長度內容。

會話機制

HTTP作爲無狀態協議,必然需要在某種方式保持連接狀態。這裏簡要介紹一下Cookie和Session。

  • Cookie

    • Cookie是客戶端保持狀態的方法。(身份認證等)

    • Cookie簡單的理解就是存儲由服務器發至客戶端並由客戶端保存的一段字符串。爲了保持會話,服務器可以在響應客戶端請求時將Cookie字符串放在Set-Cookie下,客戶機收到Cookie之後保存這段字符串,之後再請求時候帶上Cookie就可以被識別。

    • 除了上面提到的這些,Cookie在客戶端的保存形式可以有兩種,一種是會話Cookie一種是持久Cookie,會話Cookie就是將服務器返回的Cookie字符串保持在內存中,關閉瀏覽器之後自動銷燬,持久Cookie則是存儲在客戶端磁盤上,其有效時間在服務器響應頭中被指定,在有效期內,客戶端再次請求服務器時都可以直接從本地取出。需要說明的是,存儲在磁盤中的Cookie是可以被多個瀏覽器代理所共享的。

  • Session

    • Session是服務器保持狀態的方法。(記錄用戶操作、識別用戶等)

    • 首先需要明確的是,Session保存在服務器上,可以保存在數據庫、文件或內存中,每個用戶有獨立的Session用戶在客戶端上記錄用戶的操作。我們可以理解爲每個用戶有一個獨一無二的Session ID作爲Session文件的Hash鍵,通過這個值可以鎖定具體的Session結構的數據,這個Session結構中存儲了用戶操作行爲。

  • 當服務器需要識別客戶端時就需要結合Cookie了。每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用Cookie來實現Session跟蹤的,第一次創建Session的時候,服務端會在HTTP協議中告訴客戶端,需要在Cookie裏面記錄一個Session ID,以後每次請求把這個會話ID發送到服務器,我就知道你是誰了。如果客戶端的瀏覽器禁用了Cookie,會使用一種叫做URL重寫的技術來進行會話跟蹤,即每次HTTP交互,URL後面都會被附加上一個諸如sid=xxxxx這樣的參數,服務端據此來識別用戶,這樣就可以幫用戶完成諸如用戶名等信息自動填入的操作了。

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