1. 程式人生 > 其它 >HTTP之原理,長短連線,響應碼,三握四揮,八種方法

HTTP之原理,長短連線,響應碼,三握四揮,八種方法

@

目錄

學習此文章需要有OSI七層模型基礎知識

1 HTTP原理

HTTP是一個無狀態的協議。無狀態是指客戶機(Web 瀏覽器)和伺服器之間不需要建立持久的連線,這意味著當一個客戶端向伺服器端發出請求,然後伺服器返回響應(response),連線就被關閉了,在伺服器端不保留連線的有關資訊.HTTP 遵循請求(Request)/應答(Response)模型。客戶機(瀏覽器)向伺服器傳送請求,伺服器處理請求並返回適當的應答。所有 HTTP 連線都被構造成一套請求和應答

1.1 HTTP協議與TCP/IP協議的關係

HTTP的長連線和短連線本質上是TCP長連線和短連線。HTTP

屬於應用層協議,在傳輸層使用TCP協議,在網路層使用IP協議IP協議主要解決網路路由和定址問題,TCP協議主要解決如何在IP層之上可靠的傳遞資料包,使在網路上的另一端收到發端發出的所有包,並且順序與發出順序一致。TCP有可靠,面向連線的特點。

1.2 無狀態的HTTP協議

HTTP協議是無狀態的,指的是協議對於 事務處理 沒有記憶能力,伺服器不知道客戶端是什麼狀態。也就是說,開啟一個伺服器上的網頁和你之前開啟這個伺服器上的網頁之間沒有任何聯絡。HTTP是一個無狀態的面向連線的協議,無狀態不代表HTTP不能保持TCP連線,更不能代表HTTP使用的是UDP協議(無連線)。

2 長短連線詳解

2.1 簡介

HTTP/1.0中,預設使用的是短連線。也就是說,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束就中斷連線。如果客戶端瀏覽器訪問的某個HTML或其他型別的 Web頁中包含有其他的Web資源,如JavaScript檔案影象檔案CSS檔案等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話

但從 HTTP/1.1起,預設使用長連線,用以保持連線特性。使用長連線的HTTP協議,會在響應頭有加入這行程式碼:Connection:keep-alive
在使用長連線的情況下,當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸HTTP資料的 TCP連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線。Keep-Alive不會永久保持連線,它有一個保持時間,可以在不同的伺服器軟體(如Apache)中設定這個時間。實現長連線要客戶端和服務端都支援長連線。
HTTP協議的長連線和短連線,實質上是TCP協議的長連線和短連線

2.2 TCP短連線

我們模擬一下TCP短連線的情況,clientserver發起連線請求,server接到請求,然後雙方建立連線。clientserver傳送訊息,server迴應client,然後一次讀寫就完成了,這時候雙方任何一個都可以發起close操作,不過一般都是client先發起 close操作。為什麼呢,一般的server不會回覆完client後立即關閉連線的,當然不排除有特殊的情況。從上面的描述看,短連線一般只會在 client/server間傳遞一次讀寫操作
短連線的優點是:管理起來比較簡單,存在的連線都是有用的連線,不需要額外的控制手段

2.3 TCP長連線

模擬一下長連線的情況,clientserver發起連線,server接受client連線,雙方建立連線。Clientserver完成一次讀寫之後,它們之間的連線並不會主動關閉,後續的讀寫操作會繼續使用這個連線。
首先說一下TCP/IP詳解上講到的TCP保活功能,保活功能主要為伺服器應用提供,伺服器應用希望知道客戶主機是否崩潰,從而可以代表客戶使用資源。如果客戶已經消失,使得伺服器上保留一個半開放的連線,而伺服器又在等待來自客戶端的資料,則伺服器將應該等待客戶端的資料,保活功能就是試圖在伺服器端檢測到這種半開放的連線。
如果一個給定的連線在兩小時內沒有任何的動作,則伺服器就向客戶發一個探測報文段,客戶主機必須處於以下4個狀態之一:

  1. 客戶主機依然正常執行,並從伺服器可達。客戶的TCP響應正常,而伺服器也知道對方是正常的,伺服器在兩小時後將保活定時器復位。
  2. 客戶主機已經崩潰,並且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,並在75秒後超時。伺服器總共傳送10個這樣的探測 ,每個間隔75秒。如果伺服器沒有收到一個響應,它就認為客戶主機已經關閉並終止連線。
  3. 客戶主機崩潰並已經重新啟動。伺服器將收到一個對其保活探測的響應,這個響應是一個復位,使得伺服器終止這個連線。
  4. 客戶機正常執行,但是伺服器不可達,這種情況與2類似,TCP能發現的就是沒有收到探查的響應。

2.4 長連線短連線操作過程

短連線的操作步驟
建立連線——資料傳輸——關閉連線…建立連線——資料傳輸——關閉連線
長連線的操作步驟
建立連線——資料傳輸…(保持連線)…資料傳輸——關閉連線

2.5 長連線和短連線的優點和缺點

長連線可以省去較多的TCP建立和關閉的操作,減少浪費,節約時間。對於頻繁請求資源的客戶來說,較適用長連線。不過這裡存在一個問題,存活功能的探測週期太長,還有就是它只是探測TCP連線的存活,屬於比較斯文的做法,遇到惡意的連線時,保活功能就不夠使了。
在長連線的應用場景下,client端一般不會主動關閉它們之間的連線,Clientserver之間的連線如果一直不關閉的話,會存在一個問題,隨著客戶端連線越來越多,server早晚有扛不住的時候,這時候server端需要採取一些策略,如關閉一些長時間沒有讀寫事件發生的連線,這樣可以避免一些惡意連線導致server端服務受損;如果條件再允許就可以以客戶端機器為顆粒度,限制每個客戶端的最大長連線數,這樣可以完全避免某個客戶端連累後端服務。

短連線對於伺服器來說管理較為簡單,存在的連線都是有用的連線,不需要額外的控制手段。但如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費時間和頻寬。
長連線和短連線的產生在於client和server採取的關閉策略,具體的應用場景採用具體的策略,沒有十全十美的選擇,只有合適的選擇。

2.6 什麼時候用長連線,短連線

長連線多用於操作頻繁,點對點的通訊,而且連線數不能太多情況。每個TCP連線都需要三步握手,這需要時間,如果每個操作都是先連線,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,次處理時直接傳送資料包就OK了,不用建立TCP連線。
例如:資料庫的連線用長連線, 如果用短連線頻繁的通訊會造成socket錯誤,而且頻繁的socket 建立也是對資源的浪費。
而像WEB網站的http服務一般都用短連結,因為長連線對於服務端來說會耗費一定的資源,而像WEB網站這麼頻繁的成千上萬甚至上億客戶端的連線用短連線會更省一些資源,如果用長連線,而且同時有成千上萬的使用者,如果每個使用者都佔用一個連線的話,那可想而知吧。所以併發量大,但每個使用者無需頻繁操作情況下需用短連好

3 HTTP傳送過程解析

3.1 概述

HTTP協議是基於請求/響應的運作方式:

  • 建立連線 :連線的建立是瀏覽器通過建立套接字(Socket)實現的。瀏覽器開啟一個套接字並把它約束在一個埠上,就可以在該埠上寫資料並通過網路向外傳送
  • 傳送請求 :開啟一個連線後,瀏覽器把請求訊息送到伺服器的埠上,完成提出請求動作
  • 傳送響應 : 伺服器在處理完客戶的請求之後,向瀏覽器傳送響應訊息
  • 關閉連線:客戶和伺服器雙方都可以通過關閉套接字來結束TCP/IP對話

3.2 傳輸流程

  1. 地址解析
    如用客戶端瀏覽器請求這個頁面: http://localhost.com:8080/index.htm 從中分解出協議名、主機名、埠、物件路徑等部分,對於我們的這個地址,解析得到的結果如下:
    協議名: http
    主機名: localhost.com
    埠: 8080
    物件路徑: /index.htm13/04/2018 Page 165 of 283
    在這一步,需要域名系統 DNS 解析域名 localhost.com,得主機的 IP 地址
  2. 瀏覽器查詢域名的IP地址,DNS查詢過程如下:
    瀏覽器快取 – 瀏覽器會快取DNS記錄一段時間。 有趣的是,作業系統沒有告訴瀏覽器儲存DNS記錄的時間,這樣不同瀏覽器會儲存個自固定的一個時間(2分鐘到30分鐘不等)。
    系統快取 – 如果在瀏覽器快取裡沒有找到需要的記錄,瀏覽器會做一個系統呼叫(windows裡是gethostbyname)。這樣便可獲得系統快取中的記錄。
    路由器快取 – 接著,前面的查詢請求發向路由器,它一般會有自己的DNS快取
    ISP DNS 快取 – 接下來要check的就是ISP快取DNS的伺服器。在這一般都能找到相應的快取記錄。
    遞迴搜尋ISPDNS伺服器從跟域名伺服器開始進行遞迴搜尋,從.com頂級域名伺服器到Facebook的域名伺服器。一般DNS伺服器的快取中會有.com域名伺服器中的域名,所以到頂級伺服器的匹配過程不是那麼必要了

DNS有一點令人擔憂,這就是像wikipedia.org 或者 facebook.com這樣的整個域名看上去只是對應一個單獨的IP地址。還好,有幾種方法可以消除這個瓶頸:

  • 迴圈 DNSDNS查詢時返回多個IP時的解決方案。舉例來說,Facebook.com實際上就對應了四個IP地址。
  • 負載平衡器 是以一個特定IP地址進行偵聽並將網路請求轉發到叢集伺服器上的硬體裝置。 一些大型的站點一般都會使用這種昂貴的高效能負載平衡器。
  • 地理 DNS 根據使用者所處的地理位置,通過把域名對映到多個不同的IP地址提高可擴充套件性。這樣不同的伺服器不能夠更新同步狀態,但對映靜態內容的話非常好。
  • Anycast 是一個IP地址對映多個物理主機的路由技術。 美中不足,Anycast與TCP協議適應的不是很好,所以很少應用在那些方案中
  1. 封裝 HTTP 請求資料包
    把以上部分結合本機自己的資訊,封裝成一個 HTTP 請求資料包
  2. 封裝成 TCP包並建立連線
    封裝成 TCP 包,建立 TCP 連線(TCP 的三次握手)
  3. 客戶機發送請求命
    客戶機發送請求命令: 建立連線後,客戶機發送一個請求給伺服器,請求方式的格式為:統一資源識別符號(URL)、協議版本號,後邊是 MIME 資訊包括請求修飾符、客戶機資訊和可內容。
  4. 伺服器響應
    伺服器接到請求後,給予相應的響應資訊, 其格式為一個狀態行,包括資訊的協議版本號、一個成功或錯誤的程式碼,後邊是 MIME 資訊包括伺服器資訊、實體資訊和可能的內容。
  5. 伺服器關閉TCP連線
    伺服器關閉 TCP 連線: 一般情況下,一旦 Web 伺服器向瀏覽器傳送了請求資料,它就要關閉TCP連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼 Connection:keep-aliveTCP 連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。

大致結構如下所示:

3.3 請求和響應

3.3.1 一般頭欄位

一般頭欄位可用於請求訊息響應訊息

  • Cache-Contro : "max-age=10"
  • Connection : "close"
  • Date : "Tue, 11 Jul 2000 18:23:51 GMT"
  • Pragma : "no-cache"
  • Trailer : "Date"
  • Transfer-Encoding : "chunked"
  • Upgrade : "SHTTP/1.3"
  • Via : "HTTP/1.1 Proxy1, HTTP/1.1 Proxy2"
  • Warning : "112 Disconnected Operation"

3.3.2 請求報頭域

常見的HTTP請求報頭域:

  • Accept:"text/html, image/*",用於指定客戶端接受哪些型別的資訊。
  • Accept-Charset : "iso8859-5",請求端在傳送請求時的頭部資訊,這個標識的是當前客戶端可以接受的字元編碼(所謂字元編碼就是對於可見或者不可見字元的編碼方式)
  • Accept-Encoding:"gzip, compress",類似Accept,但是它是用於指定可接受的內容編碼,這個編碼與字元編碼不是一個該概念,(我們經常會用到壓縮檔案,將正常檔案進行壓縮就是一種利用檔案的底層編碼進行的再編碼)
    伺服器在發個客戶端資料的時候會將資料先根據請求資料中的Accept-Charset進行編碼,然後對資料進行壓縮,也就是說通過Accept-Encoding中可以接受的壓縮演算法進行壓縮,這會有效減小網路壓力,同時也減小了對客戶端的延時,因為段資料在伺服器進行壓縮所用的時間與在網路上傳輸的時間相比還是比較理想的
    如果請求訊息中沒有設定這個域,伺服器假定客戶端對各種內容編碼都可接受
  • Accept-Language:"en, fr",類似於Accept,但是它是用於指定一種自然語言。如果請求訊息中沒有設定這個域,伺服器假定客戶端對各種語言都可接受。
  • Authorization : [credentials],授權資訊,通常出現在對伺服器傳送的WWW-Authenticate頭的應答中
  • Expect : "100-continue",傳送一個請求, 包含一個Expect:100-continue, 詢問Server是否願意接受資料,接收到Server返回的100-continue應答以後, 才把資料POST給Server
  • Host:主要用於指定被請求資源的Internet主機和埠號,它通常是從HTTP URL中提取出來的
  • From : "xxx@xxxxcom"
  • User-Agent:"Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)",允許客戶端將它的作業系統瀏覽器和其他屬性告訴伺服器。
  • Connnection:標明客戶是否能夠處理持續性HTTP連線。持續性連線允許客戶或者瀏覽器在單個socket中讀取多個檔案,從而節省協商幾個獨立連線所需的開銷。
  • Content-Encoding : "gzip",來標識服務端壓縮時所用的壓縮方式,Accept-Encoding用來標識客戶端能夠理解的內容編碼方式。 Content-Encoding用來標識主體進行了何種方式的內容編碼轉換
  • Cookie:向伺服器返回cookie,這些cookie是之前由伺服器傳送給瀏覽器的:request.getCookies()

3.3.3 響應結構

HTTP響應由三個部分組成:

  • 狀態碼(Status Code):描述了響應的狀態。可以用來檢查是否成功的完成了請求。請求失敗的情況下,狀態碼可用來找出失敗的原因。如果Servlet沒有返回狀態碼,預設會返回成功的狀態碼HttpServletResponse.SC_OK
  • HTTP頭部(HTTP Header):它們包含了更多關於響應的資訊。比如:頭部可以指定認為響應過期的過期日期,或者是指定用來給使用者安全的傳輸實體內容的編碼格式。如何在Serlet中檢索HTTP的頭部看這裡
  • 主體(Body):它包含了響應的內容。它可以包含HTML程式碼,圖片,等等。主體是由傳輸在HTTP訊息中緊跟在頭部後面的資料位元組組成的

響應頭結構示例:

  • Range : bytes=206-5513,指定一種度量單位和一個部分被請求資源的偏移範圍。
  • Refener : www.myweb.com/news/search.html,一種請求頭標域,標明產生請求的初始資源。對於HTML表單,它包含此表單的Web頁面的地址
  • Accept-Ranges : "none",一個響應頭標,它允許伺服器指明:將在給定的偏移和長度處,為資源組成部分的接受請求。該頭標的值被理解為請求範圍的度量單位
  • Age : "2147483648(2^31)",允許伺服器規定自伺服器生成該響應以來所經過的時間長度,以秒為單位。該頭標主要用於快取響應
  • ETag : "b38b9-17dd-367c5dcd",一種實體頭標,它向被髮送的資源分派一個唯一的識別符號。對於可以使用多種URL請求的資源,ETag可以用於確定實際被髮送的資源是否為同一資源
  • Last-Modified : "Tue, 11 Jul 2000 18:23:51 GMT",指定被請求資源上次被修改的日期和時間
  • Location : "http://localhost/redirecttarget.asp",對於一個已經移動的資源,用於重定向請求者至另一個位置。與狀態編碼302(暫時移動)或者301(永久性移動)配合使用
  • Proxy-Authenticate [challenge],類似於WWW-Authenticate,便是有意請求只來自請求鏈(代理)的下一個伺服器的認證
  • Retry-After : "Tue, 11 Jul 2000 18:23:51 GMT" or "60",一種響應頭標域,由伺服器與狀態編碼503(無法提供服務)配合傳送,以標明再次請求之前應該等待多長時間,此時間即可以是一種日期,也可以是一種秒單位
  • Server : "Microsoft-IIS/5.0",一種標明Web伺服器軟體及其版本號的頭標
  • Vary : "Date",一個響應頭標,用於表示使用伺服器驅動的協商從可用的響應表示中選擇響應實體。例如:Vary: *

3.3.4 HTTP響應碼

HTTP響應碼:

  • 1xx:臨時,請求收到,繼續處理
  • 2xx:成功,行為被成功地接受、理解和採納
  • 3xx:重定向,為了完成請求,必須進一步執行的動作
  • 4xx:客戶端錯誤,請求包含語法錯誤或者請求無法實現
  • 5xx: 伺服器端錯誤,伺服器不能實現一種明顯無效的請求
響應碼 響應資訊
100 繼續,請求者應當繼續提出請求。 伺服器返回此程式碼表示已收到請求的第一部分,正在等待其餘部分
101 分組交換協議,請求者已要求伺服器切換協議,伺服器已確認並準備切換
200 OK, 伺服器已成功處理了請求。 通常,這表示伺服器提供了請求的網頁
201 已建立,請求成功並且伺服器建立了新的資源
202 已接受,伺服器已接受請求,但尚未處理
203 非授權資訊,伺服器已成功處理了請求,但返回的資訊可能來自另一來源
204 無內容,請求收到,但返回資訊為空
205 重置內容,伺服器完成了請求,使用者代理必須復位當前已經瀏覽過的檔案
206 部分內容,伺服器已經完成了部分使用者的GET請求
300 多種選擇,請求的資源可在多處得到
301 永久重定向,瀏覽器會記住,比如說從123.cn——>456.cn,瀏覽器不會請求123.cn,直接請求456.cn了
302 臨時重定向,瀏覽器不會記住,比如說從123.cn——>456.cn,瀏覽器每次都會先請求123.cn,然後再請求456.cn
303 檢視其他位置,請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,伺服器返回此程式碼,建議客戶訪問其他URL或訪問方式
304 未修改,自從上次請求後,請求的網頁未修改過。 伺服器返回此響應時,不會返回網頁內容
305 使用代理,請求者只能使用代理訪問請求的網頁。請求的資源必須從伺服器指定的地址得到
306 前一版本HTTP中使用的程式碼,現行版本中不再使用
307 暫時重定向,伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求
400 錯誤請求,如語法錯誤
401 未授權,請求要求身份驗證。 對於需要登入的網頁,伺服器可能返回此響應
402 保留有效ChargeTo頭響應,要求付費
403 禁止訪問 HTTP
404 未找到,沒有發現檔案、查詢或URl
405 方法禁用,使用者在Request-Line欄位定義的方法不允許
406 不接受,無法使用請求的內容特性響應請求的網頁
407 需要代理授權,類似401,使用者必須首先在代理伺服器上得到授權
408 請求超時,客戶端沒有在使用者指定的時間內完成請求
409 衝突,伺服器在完成請求時發生衝突。 伺服器必須在響應中包含有關衝突的資訊
410 已刪除,如果請求的資源已永久刪除,伺服器就會返回此響應
411 需要有效長度, 伺服器不接受不含有效內容長度標頭欄位的請求,伺服器拒絕使用者定義的Content-Length屬性請求
412 未滿足前提條件,伺服器未滿足請求者在請求中設定的其中一個前提條件
413 請求實體太大,請求的資源大於伺服器允許的大小
414 請求URI太大,請求的資源URL長於伺服器允許的長度
415 不支援的媒體型別,請求資源不支援請求專案格式
416 請求範圍不符合要求,如果頁面無法提供請求的範圍,則伺服器會返回此狀態程式碼
417 未滿足期望值,伺服器不滿足請求Expect頭欄位指定的期望值,如果是代理伺服器,可能是下一級伺服器不能滿足請求長,失敗的預期
500 內部伺服器錯誤
501 尚未實施,伺服器不具備完成請求的功能。 例如,伺服器無法識別請求方法時可能會返回此程式碼
502 閘道器錯誤, 伺服器作為閘道器或代理,從上游伺服器收到無效響應
503 不可用的服務,伺服器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態
504 閘道器超時,伺服器作為閘道器或代理,但是沒有及時從上游伺服器收到請求
505 HTTP版本未被支援,伺服器不支援請求中所用的 HTTP 協議版本

4 三次握手四次揮手

TCP 在傳輸之前會進行三次溝通,一般稱為三次握手,傳完資料斷開的時候要進行四次揮手

4.1 資料包說明


資料包說明:

  1. 源埠號(16 位):它(連同源主機 IP 地址)標識源主機的一個應用程序
  2. 目的埠號(16 位):它(連同目的主機 IP 地址)標識目的主機的一個應用程序。這兩個值加上 IP 報頭中的源主機 IP 地址和目的主機 IP 地址確定唯一一個 TCP 連線
  3. 順序號seq(32 位): 用來標識從 TCP 源端向 TCP 目的端傳送的資料位元組流,它表示在這個報文段中的第一個資料位元組的順序號。如果將位元組流看作在兩個應用程式間的單向流動,則TCP用順序號對每個位元組進行計數。序號是 32bit 的無符號數, 序號到達 2^32-1後又從 0 開始。 當建立一個新的連線時, SYN 標誌變1,順序號欄位包含 由這個主機選擇的 該連線的初始順序號 ISN (Initial Sequence Number )
  4. 確認號 ack(32 位): 包含傳送確認的一端所期望收到的下一個順序號。因此,確認序號應當是上次已成功收到資料位元組順序號加 1 。 只有 ACK 標誌為 1 時確認序號欄位才有效。
    TCP 為應用層提供全雙工服務,這意味資料能在兩個方向上獨立地進行傳輸。因此,連線的每一端必須保持每個方向上的傳輸資料順序號。
  5. TCP 報頭長度(4 位):給出報頭中 32bit 字的數目, 它實際上指明資料從哪裡開始。 需要這個值是因為任選欄位的長度是可變的。這個欄位佔 4bit ,因此 TCP 最多有 60 位元組的首部。然而,沒有任選欄位,正常的長度是 20位元組
  6. 保留位(6 位):保留給將來使用,目前必須置為 0 。
  7. 控制位(control flags , 6 位):在TCP報頭中有 6 個標誌位元,它們中的多個可同時被設定為 1 。依次為:
    URG :為 1 表示緊急指標有效,為 0 則忽略緊急指標值。
    ACK :為 1 表示確認號有效,為 0 表示報文中不包含確認資訊,忽略確認號欄位。
    PSH :為 1 表示是帶有 PUSH 標誌的資料, 指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿。
    RST : 用於復位由於主機崩潰或其他原因而出現錯誤的連線。它還可以用於拒絕非法的報文段和拒絕連線請求。一般情況下,如果收到一個 RST 為 1 的報文,那麼一定發生了某些問題。
    SYN :同步序號, 為 1 表示連線請求,用於建立連線和使順序號同步synchronize
    FIN : 用於釋放連線,為 1 表示傳送方已經沒有資料傳送了,即關閉本方資料流。
  8. 視窗大小(16 位):資料位元組數,表示從確認號開始,本報文的源方可以接收的位元組數,即源方接收視窗大小。視窗大小是一個 16bit 欄位,因而視窗大小最大為 65535 位元組。
  9. 校驗和(16 位):此校驗和是對整個的 TCP 報文段, 包括 TCP 頭部和 TCP 資料,以 16 位字進行計算所得。這是一個強制性的欄位,一定是由傳送端計算和儲存, 並由接收端進行驗證。
  10. 緊急指標(16 位):只有當 URG 標誌置 1 時緊急指標才有效。TCP 的緊急方式是傳送端向另一端傳送緊急資料的一種方式
  11. 選項:最常見的可選欄位是最長報文大小,又稱為 MSS(Maximum Segment Size) 。每個連線方通常都在通訊的第一個報文段(為建立連線而設定 SYN 標誌的那個段)中指明這個選項,它指明本端所能接收的最大長度的報文段。選項長度不一定是 32 位字的整數倍,所以要加填充位,使得報頭長度成為整字數。
  12. 資料TCP 報文段中的資料部分是可選的。在一個連線建立和一個連線終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有資料要傳送,也使用沒有任何資料的首部來確認收到的資料。在處理超時的許多情況中,也會發送不帶任何資料的報文段

4.2 三次握手

  1. 第一次握手:主機 A 傳送位碼為 syn=1,隨機產生 seq number=1234567 的資料包到伺服器,主機 B 由 SYN=1 知道, A 要求建立聯機;
  2. 第二次握手:主 機 B 收 到 請 求 後 要 確 認 聯 機 信 息 , 向 A 發 送 ack number=( 主 機 A 的seq+1),SYN=1,ACK=1,隨機產生 seq=7654321 的包
  3. 第三次握手: 主機 A 收到後檢查 ack number 是否正確,即第一次傳送的 seq number+1,以及位碼ACK 是否為 1,若正確, 主機 A 會再發送 ack number=(主機 B 的 seq+1),ACK=1,主機 B 收到後確認seq 值ACK=1 則連線建立成功

4.3 四次揮手

TCP 建立連線要進行三次握手,而斷開連線要進行四次。這是由於 TCP 的半關閉造成的。因為 TCP 連線是全雙工的(即資料可在兩個方向上同時傳遞)所以進行關閉時每個方向上都要單獨進行關閉。這個單方向的關閉就叫半關閉。當一方完成它的資料傳送任務,就傳送一個 FIN 來向另一方通告將要終止這個方向的連線

首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉

  1. 關閉客戶端到伺服器的連線:首先客戶端 A 傳送一個 FIN,用來關閉客戶到伺服器的資料傳送,然後等待伺服器的確認。其中終止標誌位 FIN=1,序列號 seq=u
  2. 伺服器收到這個 FIN,它發回一個 ACK,確認號 ack 為收到的序號加 1
  3. 關閉伺服器到客戶端的連線:也是傳送一個 FIN 給客戶端。
  4. 客戶段收到 FIN 後,併發回一個 ACK 報文確認,並將確認序號 seq 設定為收到序號加 1

主機 A 傳送 FIN 後,進入終止等待狀態, 伺服器 B 收到主機 A 連線釋放報文段後,就立即給主機 A 傳送確認,然後伺服器 B 就進入 close-wait 狀態,此時 TCP 伺服器程序就通知高層應用程序,因而從 A 到 B 的連線就釋放了。此時是半關閉狀態。即 A 不可以傳送給B,但是 B 可以傳送給 A。此時,若 B 沒有資料報要傳送給 A 了,其應用程序就通知 TCP 釋放連線,然後傳送給 A 連線釋放報文段,並等待確認。 A 傳送確認後,進入 time-wait
注意,此時 TCP 連線還沒有釋放掉,然後經過時間等待計時器設定的 2MSL 後, A 才進入到close狀態

5 HTTP1.1協議八種方法

5.1 定義

http協議請求由三部分組成,分別是:請求行訊息報頭請求正文
請求行以一個方法符號開頭,以空格分開,後面跟著請求的URI協議的版本,格式如下: 

Method Request-URI HTTP-Version CRLF

HTTP/1.1協議中共定義了八種方法(有時也叫動作)來表明Request-URI指定的資源的不同操作方式:

  1. OPTIONS
    返回伺服器針對特定資源所支援的HTTP請求方法。也可以利用向Web伺服器傳送*的請求來測試伺服器的功能性
  2. HEAD
    向伺服器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應訊息頭中的元資訊。
  3. GET
    向特定的資源發出請求。注意:GET方法不應當被用於產生副作用的操作中
  4. POST
    向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改
  5. PUT
    向指定資源位置上傳其最新內容。
  6. DELETE
    請求伺服器刪除Request-URI所標識的資源。
  7. TRACE
    回顯伺服器收到的請求,主要用於測試或診斷。
  8. CONNECT
    HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。

5.2 get和post提交區別

簡單來說,本質上區別:

  • GET產生 一個 TCP資料包
  • POST產生 兩個 TCP資料包

也就是說:

對於GET方式的請求,瀏覽器會把http headerdata一併傳送出去,伺服器響應200(返回資料);
而對於POST,瀏覽器先發送header,伺服器響應100 continue,瀏覽器再發送data,伺服器響應200 ok(返回資料)

詳細區別:

  • 資料攜帶上:
    GET方式:在URL地址後附帶的引數是有限制的,其資料容量通常不能超過1K
    POST方式:可以在請求的實體內容中向伺服器傳送資料,傳送的資料量無限制。

  • 請求引數的位置上:
    GET方式:請求引數放在URL地址後面,以 ? 的方式來進行拼接
    POST方式:請求引數放在HTTP請求包中

  • 用途上:
    GET方式一般用來獲取資料
    POST方式一般用來提交資料
    首先是因為GET方式攜帶的資料量比較小,無法帶過去很大的數量
    POST方式提交的引數後臺更加容易解析(使用POST方式提交的中文資料,後臺也更加容易解決)
    GET方式比POST方式要快

  • GET方式比POST方式要快
    post請求包含更多的請求頭
    因為post需要在請求的body部分包含資料,所以會多了幾個資料描述部分的首部欄位(如content-type),這其實是微乎其微的。
    post在真正接受資料之前會先將請求頭髮送給伺服器進行確認,然後才真正傳送資料

  • post請求的過程:
    [1] 瀏覽器請求tcp連線(第一次握手)
    [2] 伺服器答應進行tcp連線(第二次握手)
    [3] 瀏覽器確認,併發送post請求頭(第三次握手,這個報文比較小,所以http會在此時進行第一次資料傳送)
    ​[4] 伺服器返回100 continue響應
    [5] 瀏覽器開始傳送資料
    [6] 伺服器返回200 ok響應

  • get請求的過程:
    [1] 瀏覽器請求tcp連線(第一次握手)
    [2] 伺服器答應進行tcp連線(第二次握手)
    [3] 瀏覽器確認,併發送get請求頭和資料(第三次握手,這個報文比較小,所以http會在此時進行第一次資料傳送)
    [4] 伺服器返回200 ok響應
    也就是說,目測get的總耗是post2/3左右
    get會將資料快取起來,而post不會
    post不能進行管道化傳輸

FORM提交的時候,如果不指定Method,則預設為get請求,Form中提交的資料將會附加在url之後,以?分開與url分開。字母數字字元原樣傳送,但空格轉換為+號,其它符號轉換為%XX, 其中XX為該符號以16進位制表示的ASCII(或ISOLatin-1)值。get請求請提交的資料放置在HTTP請求協議頭中,而post提交的資料則 放在實體資料中;
get方式提交的資料最多隻能有1024位元組,而post則沒有此限制
在表單裡使用postget有什麼區別
Form裡面,可以使用post也可以使用get。它們都是method的合法取值。但是,postget方法在使用上至少有兩點不同:

  1. get方法通過URL請求來傳遞使用者的輸入。post方法通過另外的形式。
  2. get方式的提交需要用Request.QueryString來取得變數的值,而post方式提交時,必須通過Request.Form來訪問提交的內容。