HTTP之原理,長短連線,響應碼,三握四揮,八種方法
@
目錄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
短連線的情況,client
向server
發起連線請求,server
接到請求,然後雙方建立連線。client
向server
傳送訊息,server
迴應client
,然後一次讀寫就完成了,這時候雙方任何一個都可以發起close
操作,不過一般都是client
先發起 close
操作。為什麼呢,一般的server
不會回覆完client
後立即關閉連線的,當然不排除有特殊的情況。從上面的描述看,短連線一般只會在 client/server
間傳遞一次讀寫操作
短連線的優點是:管理起來比較簡單,存在的連線都是有用的連線,不需要額外的控制手段
2.3 TCP長連線
模擬一下長連線的情況,client
向server
發起連線,server
接受client
連線,雙方建立連線。Client
與server
完成一次讀寫之後,它們之間的連線並不會主動關閉,後續的讀寫操作會繼續使用這個連線。
首先說一下TCP/IP
詳解上講到的TCP
保活功能,保活功能主要為伺服器應用提供,伺服器應用希望知道客戶主機是否崩潰,從而可以代表客戶使用資源。如果客戶已經消失,使得伺服器上保留一個半開放的連線,而伺服器又在等待來自客戶端的資料,則伺服器將應該等待客戶端的資料,保活功能就是試圖在伺服器端檢測到這種半開放的連線。
如果一個給定的連線在兩小時內沒有任何的動作,則伺服器就向客戶發一個探測報文段,客戶主機必須處於以下4個狀態之一:
- 客戶主機依然正常執行,並從伺服器可達。客戶的TCP響應正常,而伺服器也知道對方是正常的,伺服器在兩小時後將保活定時器復位。
- 客戶主機已經崩潰,並且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,並在75秒後超時。伺服器總共傳送10個這樣的探測 ,每個間隔75秒。如果伺服器沒有收到一個響應,它就認為客戶主機已經關閉並終止連線。
- 客戶主機崩潰並已經重新啟動。伺服器將收到一個對其保活探測的響應,這個響應是一個復位,使得伺服器終止這個連線。
- 客戶機正常執行,但是伺服器不可達,這種情況與2類似,TCP能發現的就是沒有收到探查的響應。
2.4 長連線短連線操作過程
短連線的操作步驟
建立連線——資料傳輸——關閉連線…建立連線——資料傳輸——關閉連線
長連線的操作步驟
建立連線——資料傳輸…(保持連線)…資料傳輸——關閉連線
2.5 長連線和短連線的優點和缺點
長連線可以省去較多的TCP
建立和關閉的操作,減少浪費,節約時間。對於頻繁請求資源的客戶來說,較適用長連線。不過這裡存在一個問題,存活功能的探測週期太長,還有就是它只是探測TCP
連線的存活,屬於比較斯文的做法,遇到惡意的連線時,保活功能就不夠使了。
在長連線的應用場景下,client
端一般不會主動關閉它們之間的連線,Client
與server
之間的連線如果一直不關閉的話,會存在一個問題,隨著客戶端連線越來越多,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 傳輸流程
- 地址解析
如用客戶端瀏覽器請求這個頁面:http://localhost.com:8080/index.htm
從中分解出協議名、主機名、埠、物件路徑等部分,對於我們的這個地址,解析得到的結果如下:
協議名:http
主機名:localhost.com
埠:8080
物件路徑:/index.htm13/04/2018 Page 165 of 283
在這一步,需要域名系統DNS
解析域名localhost.com
,得主機的 IP 地址 - 瀏覽器查詢域名的IP地址,
DNS
查詢過程如下:瀏覽器快取
– 瀏覽器會快取DNS
記錄一段時間。 有趣的是,作業系統沒有告訴瀏覽器儲存DNS
記錄的時間,這樣不同瀏覽器會儲存個自固定的一個時間(2分鐘到30分鐘不等)。系統快取
– 如果在瀏覽器快取裡沒有找到需要的記錄,瀏覽器會做一個系統呼叫(windows
裡是gethostbyname
)。這樣便可獲得系統快取中的記錄。路由器快取
– 接著,前面的查詢請求發向路由器,它一般會有自己的DNS
快取ISP DNS 快取
– 接下來要check
的就是ISP快取DNS
的伺服器。在這一般都能找到相應的快取記錄。遞迴搜尋
–ISP
的DNS伺服器
從跟域名伺服器開始進行遞迴搜尋,從.com
頂級域名伺服器到Facebook
的域名伺服器。一般DNS伺服器的快取中會有.com域名伺服器中的域名,所以到頂級伺服器的匹配過程不是那麼必要了
DNS
有一點令人擔憂,這就是像wikipedia.org 或者 facebook.com這樣的整個域名看上去只是對應一個單獨的IP地址。還好,有幾種方法可以消除這個瓶頸:
迴圈 DNS
是DNS
查詢時返回多個IP時的解決方案。舉例來說,Facebook.com實際上就對應了四個IP地址。負載平衡器
是以一個特定IP地址進行偵聽並將網路請求轉發到叢集伺服器上的硬體裝置。 一些大型的站點一般都會使用這種昂貴的高效能負載平衡器。地理 DNS
根據使用者所處的地理位置,通過把域名對映到多個不同的IP地址提高可擴充套件性。這樣不同的伺服器不能夠更新同步狀態,但對映靜態內容的話非常好。Anycast
是一個IP地址對映多個物理主機的路由技術。 美中不足,Anycast與TCP協議適應的不是很好,所以很少應用在那些方案中
- 封裝
HTTP
請求資料包
把以上部分結合本機自己的資訊,封裝成一個HTTP
請求資料包 - 封裝成
TCP
包並建立連線
封裝成 TCP 包,建立 TCP 連線(TCP 的三次握手) - 客戶機發送請求命
客戶機發送請求命令: 建立連線後,客戶機發送一個請求給伺服器,請求方式的格式為:統一資源識別符號(URL)、協議版本號,後邊是 MIME 資訊包括請求修飾符、客戶機資訊和可內容。 - 伺服器響應
伺服器接到請求後,給予相應的響應資訊, 其格式為一個狀態行,包括資訊的協議版本號、一個成功或錯誤的程式碼,後邊是 MIME 資訊包括伺服器資訊、實體資訊和可能的內容。 - 伺服器關閉
TCP
連線
伺服器關閉TCP
連線: 一般情況下,一旦Web
伺服器向瀏覽器傳送了請求資料,它就要關閉TCP
連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼Connection:keep-alive
,TCP
連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。
大致結構如下所示:
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 資料包說明
資料包說明:
-
源埠號
(16 位):它(連同源主機 IP 地址)標識源主機的一個應用程序 -
目的埠號
(16 位):它(連同目的主機 IP 地址)標識目的主機的一個應用程序。這兩個值加上 IP 報頭中的源主機 IP 地址和目的主機 IP 地址確定唯一一個 TCP 連線 -
順序號seq
(32 位): 用來標識從TCP
源端向TCP
目的端傳送的資料位元組流,它表示在這個報文段中的第一個資料位元組的順序號。如果將位元組流看作在兩個應用程式間的單向流動,則TCP
用順序號對每個位元組進行計數。序號是32bit
的無符號數, 序號到達2^32-1
後又從 0 開始。 當建立一個新的連線時,SYN
標誌變1
,順序號欄位包含 由這個主機選擇的 該連線的初始順序號ISN (Initial Sequence Number )
-
確認號 ack
(32 位): 包含傳送確認的一端所期望收到的下一個順序號。因此,確認序號應當是上次已成功收到資料位元組順序號加 1
。 只有ACK
標誌為 1 時確認序號欄位才有效。TCP
為應用層提供全雙工服務,這意味資料能在兩個方向上獨立地進行傳輸。因此,連線的每一端必須保持每個方向上的傳輸資料順序號。 -
TCP
報頭長度(4 位):給出報頭中32bit
字的數目, 它實際上指明資料從哪裡開始。 需要這個值是因為任選欄位的長度是可變的。這個欄位佔4bit
,因此TCP
最多有 60 位元組的首部。然而,沒有任選欄位,正常的長度是20位元組
-
保留位
(6 位):保留給將來使用,目前必須置為 0 。 -
控制位
(control flags
, 6 位):在TCP
報頭中有 6 個標誌位元,它們中的多個可同時被設定為 1 。依次為:URG
:為 1 表示緊急指標有效,為 0 則忽略緊急指標值。ACK
:為 1 表示確認號有效,為 0 表示報文中不包含確認資訊,忽略確認號欄位。PSH
:為 1 表示是帶有PUSH
標誌的資料, 指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿。RST
: 用於復位由於主機崩潰或其他原因而出現錯誤的連線。它還可以用於拒絕非法的報文段和拒絕連線請求。一般情況下,如果收到一個RST
為 1 的報文,那麼一定發生了某些問題。SYN
:同步序號, 為 1 表示連線請求,用於建立連線和使順序號同步synchronize
FIN
: 用於釋放連線,為 1 表示傳送方已經沒有資料傳送了,即關閉本方資料流。 -
視窗大小
(16 位):資料位元組數,表示從確認號開始,本報文的源方可以接收的位元組數,即源方接收視窗大小。視窗大小是一個16bit
欄位,因而視窗大小最大為65535
位元組。 -
校驗和
(16 位):此校驗和是對整個的TCP
報文段, 包括TCP
頭部和TCP
資料,以 16 位字進行計算所得。這是一個強制性的欄位,一定是由傳送端計算和儲存, 並由接收端進行驗證。 -
緊急指標
(16 位):只有當URG
標誌置 1 時緊急指標才有效。TCP
的緊急方式是傳送端向另一端傳送緊急資料的一種方式 -
選項
:最常見的可選欄位是最長報文大小,又稱為MSS(Maximum Segment Size)
。每個連線方通常都在通訊的第一個報文段(為建立連線而設定 SYN 標誌的那個段)中指明這個選項,它指明本端所能接收的最大長度的報文段。選項長度不一定是 32 位字的整數倍,所以要加填充位,使得報頭長度成為整字數。 -
資料
:TCP
報文段中的資料部分是可選的。在一個連線建立和一個連線終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有資料要傳送,也使用沒有任何資料的首部來確認收到的資料。在處理超時的許多情況中,也會發送不帶任何資料的報文段
4.2 三次握手
- 第一次握手:主機 A 傳送位碼為
syn=1
,隨機產生seq number=1234567
的資料包到伺服器,主機 B 由SYN=1
知道, A 要求建立聯機; - 第二次握手:主 機 B 收 到 請 求 後 要 確 認 聯 機 信 息 , 向 A 發 送
ack number=( 主 機 A 的seq+1),SYN=1,ACK=1
,隨機產生seq=7654321
的包 - 第三次握手: 主機 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
來向另一方通告將要終止這個方向的連線
首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉
- 關閉客戶端到伺服器的連線:首先客戶端 A 傳送一個
FIN
,用來關閉客戶到伺服器的資料傳送,然後等待伺服器的確認。其中終止標誌位FIN=1
,序列號seq=u
- 伺服器收到這個
FIN
,它發回一個ACK
,確認號ack
為收到的序號加 1 - 關閉伺服器到客戶端的連線:也是傳送一個
FIN
給客戶端。 - 客戶段收到
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
指定的資源的不同操作方式:
-
OPTIONS
返回伺服器針對特定資源所支援的HTTP
請求方法。也可以利用向Web
伺服器傳送*
的請求來測試伺服器的功能性 -
HEAD
向伺服器索要與GET
請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應訊息頭中的元資訊。 -
GET
向特定的資源發出請求。注意:GET
方法不應當被用於產生副作用
的操作中 -
POST
向指定資源提交資料進行處理請求(例如提交表單
或者上傳檔案
)。資料被包含在請求體中。POST
請求可能會導致新的資源的建立和/或已有資源的修改 -
PUT
向指定資源位置上傳其最新內容。 -
DELETE
請求伺服器刪除Request-URI
所標識的資源。 -
TRACE
回顯伺服器收到的請求,主要用於測試或診斷。 -
CONNECT
HTTP/1.1
協議中預留給能夠將連線改為管道方式的代理伺服器。
5.2 get和post提交區別
簡單來說,本質上區別:
-
GET
產生 一個 TCP資料包 -
POST
產生 兩個 TCP資料包
也就是說:
對於
GET
方式的請求,瀏覽器會把http header
和data
一併傳送出去,伺服器響應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
的總耗是post
的2/3
左右get
會將資料快取起來,而post
不會post
不能進行管道化傳輸
在FORM
提交的時候,如果不指定Method
,則預設為get
請求,Form
中提交的資料將會附加在url
之後,以?
分開與url
分開。字母數字字元原樣傳送,但空格轉換為+
號,其它符號轉換為%XX
, 其中XX
為該符號以16進位制
表示的ASCII
(或ISOLatin-1
)值。get
請求請提交的資料放置在HTTP
請求協議頭中,而post
提交的資料則 放在實體資料中;get
方式提交的資料最多隻能有1024
位元組,而post
則沒有此限制
在表單裡使用post
和get
有什麼區別
在Form
裡面,可以使用post
也可以使用get
。它們都是method
的合法取值。但是,post
和get
方法在使用上至少有兩點不同:
-
get
方法通過URL
請求來傳遞使用者的輸入。post
方法通過另外的形式。 -
get
方式的提交需要用Request.QueryString
來取得變數的值,而post
方式提交時,必須通過Request.Form
來訪問提交的內容。