一次完整的HTTP請求與響應涉及哪些知識?

2021-03-02 Java技術棧

Java技術棧

www.javastack.cn

優秀的Java技術公眾號

作者:Ruheng

地址:http://www.jianshu.com/p/c1d6a294d3c0

本文以HTTP請求和響應的過程來講解涉及到的相關知識點。



圖片來自:理解Http請求與響應http://android.jobbole.com/85218/

以上完整表示了HTTP請求和響應的7個步驟,下面從TCP/IP協議模型的角度來理解HTTP請求和響應如何傳遞的。

TCP/IP協議模型(Transmission Control Protocol/Internet Protocol),包含了一系列構成網際網路基礎的網絡協議,是Internet的核心協議,通過20多年的發展已日漸成熟,並被廣泛應用於區域網和廣域網中,目前已成為事實上的國際標準。TCP/IP協議簇是一組不同層次上的多個協議的組合,通常被認為是一個四層協議系統,與OSI的七層模型相對應。

HTTP協議就是基於TCP/IP協議模型來傳輸信息的。



(1). 鏈路層

也稱作數據鏈路層或網絡接口層(在第一個圖中為網絡接口層和硬體層),通常包括作業系統中的設備驅動程序和計算機中對應的網絡接口卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理接口細節。ARP(地址解析協議)和RARP(逆地址解析協議)是某些網絡接口(如乙太網和令牌環網)使用的特殊協議,用來轉換IP層和網絡接口層使用的地址。

(2). 網絡層

也稱作網際網路層(在第一個圖中為網際層),處理分組在網絡中的活動,例如分組的選路。在TCP/IP協議族中,網絡層協議包括IP協議(網際協議),ICMP協議(Internet網際網路控制報文協議),以及IGMP協議(Internet組管理協議)。

IP是一種網絡層協議,提供的是一種不可靠的服務,它只是儘可能快地把分組從源結點送到目的結點,但是並不提供任何可靠性保證。同時被TCP和UDP使用。TCP和UDP的每組數據都通過端系統和每個中間路由器中的IP層在網際網路中進行傳輸。

ICMP是IP協議的附屬協議。IP層用它來與其他主機或路由器交換錯誤報文和其他重要信息。

IGMP是Internet組管理協議。它用來把一個UDP數據報多播到多個主機。

(3). 傳輸層

主要為兩臺主機上的應用程式提供端到端的通信。在TCP/IP協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(用戶數據報協議)。

TCP為兩臺主機提供高可靠性的數據通信。它所做的工作包括把應用程式交給它的數據分成合適的小塊交給下面的網絡層,確認接收到的分組,設置發送最後確認分組的超時時鐘等。由於運輸層提供了高可靠性的端到端的通信,因此應用層可以忽略所有這些細節。為了提供可靠的服務,TCP採用了超時重傳、發送和接收端到端的確認分組等機制。

UDP則為應用層提供一種非常簡單的服務。它只是把稱作數據報的分組從一臺主機發送到另一臺主機,但並不保證該數據報能到達另一端。一個數據報是指從發送方傳輸到接收方的一個信息單元(例如,發送方指定的一定字節數的信息)。UDP協議任何必需的可靠性必須由應用層來提供。
(4). 應用層

應用層決定了向用戶提供應用服務時通信的活動。TCP/IP 協議族內預存了各類通用的應用服務。包括 HTTP,FTP(File Transfer Protocol,文件傳輸協議),DNS(Domain Name System,域名系統)服務。



當應用程式用TCP傳送數據時,數據被送入協議棧中,然後逐個通過每一層直到被當作一串比特流送入網絡。其中每一層對收到的數據都要增加一些首部信息(有時還要增加尾部信息),該過程如圖所示。



當目的主機收到一個乙太網數據幀時,數據就開始從協議棧中由底向上升,同時去掉各層協議加上的報文首部。每層協議盒都要去檢查報文首部中的協議標識,以確定接收數據的上層協議。這個過程稱作分用(Demultiplexing)。協議是通過目的埠號、源I P地址和源埠號進行解包的。

通過以上步驟我們從TCP/IP模型的角度來理解了一次HTTP請求與響應的過程。

下面這張圖更清楚明白:


下面具體來看如何進行一步步操作的。

TCP是面向連接的,無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。在TCP/IP協議中,TCP協議提供可靠的連接服務,連接是通過三次握手進行初始化的。三次握手的目的是同步連接雙方的序列號和確認號並交換 TCP窗口大小信息。


第一次握手:建立連接。客戶端發送連接請求報文段,將SYN位置為1,Sequence Number為x;然後,客戶端進入SYN_SEND狀態,等待伺服器的確認;

第二次握手:伺服器收到SYN報文段。伺服器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設置Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要發送SYN請求信息,將SYN位置為1,Sequence Number為y;伺服器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一併發送給客戶端,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK報文段。然後將Acknowledgment Number設置為y+1,向伺服器發送ACK報文段,這個報文段發送完畢以後,客戶端和伺服器端都進入ESTABLISHED狀態,完成TCP三次握手。

為什麼要三次握手

為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

具體例子:「已失效的連接請求報文段」的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用「三次握手」,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。採用「三次握手」的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。」

Http是什麼?

通俗來講,他就是計算機通過網絡進行通信的規則,是一個基於請求與響應,無狀態的,應用層的協議,常基於TCP/IP協議傳輸數據。目前任何終端(手機,筆記本電腦。。)之間進行任何一種通信都必須按照Http協議進行,否則無法連接。

四個基於:

請求與響應:客戶端發送請求,伺服器端響應數據

無狀態的:協議對於事務處理沒有記憶能力,客戶端第一次與伺服器建立連接發送請求時需要進行一系列的安全認證匹配等,因此增加頁面等待時間,當客戶端向伺服器端發送請求,伺服器端響應完畢後,兩者斷開連接,也不保存連接狀態,一刀兩斷!恩斷義絕!從此路人!下一次客戶端向同樣的伺服器發送請求時,由於他們之前已經遺忘了彼此,所以需要重新建立連接。

應用層:Http是屬於應用層的協議,配合TCP/IP使用。

TCP/IP:Http使用TCP作為它的支撐運輸協議。HTTP客戶機發起一個與伺服器的TCP連接,一旦連接建立,瀏覽器(客戶機)和伺服器進程就可以通過套接字接口訪問TCP。

針對無狀態的一些解決策略:

有時需要對用戶之前的HTTP通信狀態進行保存,比如執行一次登陸操作,在30分鐘內所有的請求都不需要再次登陸。於是引入了Cookie技術。

HTTP/1.1想出了持久連接(HTTP keep-alive)方法。其特點是,只要任意一端沒有明確提出斷開連接,則保持TCP連接狀態,在請求首部欄位中的Connection: keep-alive即為表明使用了持久連接。
等等還有很多。。。。。。

下面開始講解重頭戲:HTTP請求報文,響應報文,對應於上述步驟的2,3,4,5,6。

HTTP報文是面向文本的,報文中的每一個欄位都是一些ASCII碼串,各個欄位的長度是不確定的。HTTP有兩類報文:請求報文和響應報文。

一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成,下圖給出了請求報文的一般格式。


1.請求行

請求行分為三個部分:請求方法、請求地址和協議版本

請求方法

HTTP/1.1 定義的請求方法有8種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。

最常的兩種GET和POST,如果是RESTful接口的話一般會用到GET、POST、DELETE、PUT。

請求地址

URL:統一資源定位符,是一種自願位置的抽象唯一識別方法。

組成:<協議>://<主機>:<埠>/<路徑>

埠和路徑有時可以省略(HTTP默認埠號是80)

如下例:



有時會帶參數,GET請求

協議版本

協議版本的格式為:HTTP/主版本號.次版本號,常用的有HTTP/1.0和HTTP/1.1

2.請求頭部

請求頭部為請求報文添加了一些附加信息,由「名/值」對組成,每行一對,名和值之間使用冒號分隔。

常見請求頭如下:



請求頭部的最後會有一個空行,表示請求頭部結束,接下來為請求數據,這一行非常重要,必不可少。

3.請求數據

可選部分,比如GET請求就沒有請求數據。

下面是一個POST方法的請求報文:

POST  /index.php HTTP/1.1    請求行
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2  請求頭
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
  空行
username=aa&password=1234  請求數據



HTTP響應報文主要由狀態行、響應頭部、空行以及響應數據組成。

1.狀態行

由3部分組成,分別為:協議版本,狀態碼,狀態碼描述。

其中協議版本與請求報文一致,狀態碼描述是對狀態碼的簡單描述,所以這裡就只介紹狀態碼。

狀態碼

狀態代碼為3位數字。
1xx:指示信息--表示請求已接收,繼續處理。
2xx:成功--表示請求已被成功接收、理解、接受。
3xx:重定向--要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。
5xx:伺服器端錯誤--伺服器未能實現合法的請求。

下面列舉幾個常見的:兩張趣圖助你理解 HTTP 狀態碼!


2.響應頭部

與請求頭部類似,為響應報文添加了一些附加信息

常見響應頭部如下:


3.響應數據

用於存放需要返回給客戶端的數據信息。

下面是一個響應報文的實例:

HTTP/1.1 200 OK  狀態行
Date: Sun, 17 Mar 2013 08:12:54 GMT  響應頭部
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
  空行

<html>  響應數據
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>

關於請求頭部和響應頭部的知識點很多,這裡只是簡單介紹。

通過以上步驟,數據已經傳遞完畢,HTTP/1.1會維持持久連接,但持續一段時間總會有關閉連接的時候,這時候據需要斷開TCP連接。

當客戶端和伺服器通過三次握手建立了TCP連接以後,當數據傳送完畢,肯定是要斷開TCP連接的啊。那對於TCP的斷開連接,這裡就有了神秘的「四次分手」。



第一次分手:主機1(可以使客戶端,也可以是伺服器端),設置Sequence Number,向主機2發送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有數據要發送給主機2了;

第二次分手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我「同意」你的關閉請求;

第三次分手:主機2向主機1發送FIN報文段,請求關閉連接,同時主機2進入LAST_ACK狀態;

第四次分手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連接;此時,主機1等待2MSL後依然沒有收到回復,則證明Server端已正常關閉,那好,主機1也可以關閉連接了。

為什麼要四次分手

TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP是全雙工模式,這就意味著,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2,它的數據已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的數據;當主機2返回ACK報文段時,表示它已經知道主機1沒有數據發送了,但是主機2還是可以發送數據到主機1的;當主機2也發送了FIN報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,之後彼此就會愉快的中斷這次TCP連接。

通過以上步驟便完成了HTTP的請求和響應,進行了數據傳遞,這其中涉及到需要知識點,都進行了逐一了解。

Java之外,你真有必要學學Go了

Spring 系列乾貨,2019最新整理版!

你真的搞懂 transient  關鍵字了嗎?

推薦一個技術圈子,30k的offer靠它了!

分享一份Java架構師學習資料!

相關焦點

  • Jmeter之HTTP請求與響應
    HTTP請求詳解一個http請求指從客戶端到服務端的請求信息,我們可以通過瀏覽器的F12鍵,可以看到以下信息:1.請求地址:uri>2.請求方法:HEAD,GET,POST,PUT,OPTIONS,DELETE,PATCH3.HTTP協議/版本:可以打開瀏覽器按下F12仔細查看4.請求頭
  • HTTP協議請求(request)和響應(response)報文分析
    在HTTP連接中報文分為請求(request)和響應(response)兩種。每種報文在HTTP首部都有不同的欄位來標識不同的用途。1. 請求報文:HTTP協議使用TCP協議進行傳輸,在應用層協議發起交互之前,首先是TCP的三次握手。
  • Go中的HTTP請求之——HTTP1.1請求流程分析
    大綱前言http是目前應用最為廣泛, 也是程式設計師接觸最多的協議之一。今天筆者站在GoPher的角度對http1.1的請求流程進行全面的分析。在上述源碼中,pc.readResponse(rc,trace)會從連接的讀buffer中獲取一個請求對應的Response。讀到響應之後判斷請求是否是HEAD請求或者響應內容為空,如果是HEAD請求或者響應內容為空則將響應寫入rc.ch, 並將連接放入idleConn(此處因為篇幅的原因省略了源碼內容, 正常請求的邏輯也有寫響應和將連接放入idleConn兩個步驟)。
  • Linux使用epoll異步發送http請求
    http是基於tcp的協議,在發送http請求之前,要先與伺服器建立tcp連接,然後才可以發送HTTP請求。HTTP請求的頭部,就是一些以\r\n分割的字符串。第一行為GET、POST方法,之後的每一行為冒號分割的鍵值對,表示http請求的一些信息。
  • 問題回答:Http 請求的Post 和Put 的區別
    但實際上, http 請求的 post 和 put分別具體實現什麼樣的功能,都是由程式設計師在寫服務端代碼時決定的。一個 post 請求和一個 put 請求上攜帶的信息量是一樣的,同樣的 http 請求頭(header),同樣的 http 請求體(body),唯一不同的是請求方法名,一個叫 post,一個叫 put。理論上來說程式設計師完全可以實現功能一樣的處理函數來處理 post 請求和 put請求。
  • jmeter(五)HTTP請求
    建議使用一個有意義的名稱2)注釋:對於測試沒任何影響,僅用來記錄用戶可讀的注釋信息3)伺服器名稱或IP:http請求發送的目標伺服器名稱或者IP位址,比如http://www.baidu.com4)埠號:目標伺服器的埠號,默認值為80,可不填5)協議:向目標伺服器發送http請求時的協議,http/https,大小寫不敏感,默認http
  • HTTP POST請求步驟詳解
    HTTP POST請求是使用post方式提交http請求,來獲取數據。該步驟有「常規」、「欄位」兩個標籤頁。「常規」標籤頁配置信息如圖1所示。
  • HTTP
    問題或建議,請公眾號留言跟著BU科研通,學習路上更輕鬆~2 Response報文3 常用方法4 HTTP請求完整過程一 Request報文HTTP的請求報文包括:請求行(request line)、請求頭部(header)、空行 和 請求數據(request data)
  • Fetch還是Axios——哪個更適合HTTP請求?
    幾年前,大多數應用程式都使用Ajax發送HTTP請求,Ajax代表異步Javascript和XML。但是現在,開發人員通常會決定在fetch() API和Axios之間進行選擇。在本文中,我想比較這兩種方法,並簡要介紹一下基本知識和語法。除此之外,我還將比較在兩種情況下以及在錯誤處理中將數據轉換為JSON格式的過程。我還將討論HTTP攔截和下載進度。
  • SAP ABAP應用伺服器的HTTP響應狀態碼(Status Code)
    本文記錄了2016年時,SAP成都研究院CRM開發團隊在開發SAP CRM Fiori應用時的一些技術討論,關於HTTP請求的響應狀態碼的差異。當時我們用Chrome打開SAP Fiori應用,在Chrome開發者工具的network標籤裡,觀察到有的請求響應碼為HTTP 200,有的卻是HTTP 304.
  • 用JavaScript發出HTTP請求的不同方法
    });優點:· 使用promise避免回調地獄· 在瀏覽器和Nodejs上均可使用· 支持上傳進度· 可以設置響應超時· 社區的知名庫· 發出HTTP請求的無縫接口· 出現故障時支持重試請求缺點:· 它不支持以XMLHttpRequest的形式監視加載進度
  • easyhttp v1.1發布,新增異步並發請求
    1、新增異步並發請求use Gouguoyin\EasyHttp\Response;use Gouguoyin\EasyHttp\RequestException;$promises = [ Http::getAsync('http://easyhttp.gouguoyin.cn/api/sleep3.json'), Http::getAsync('http1://easyhttp.gouguoyin.cn
  • Fetch還是Axios,哪個更適合HTTP請求?
    幾年前,大多數應用程式都使用Ajax發送HTTP請求,Ajax代表異步JavaScript和XML。但是現在,開發人員通常會決定在 .fetch() API和Axios之間進行選擇。在本文中,我想比較這兩種方法,並簡要介紹一下基本知識和語法。除此之外,我還將比較在兩種情況下以及在錯誤處理中將數據轉換為jsON格式的過程。我還將討論HTTP攔截和下載進度。
  • 聊聊http的幾種請求方法
    要徹底掌握這些 request methods,我們需要從幾方面問題來考慮:該 請求方法 的設計初衷是什麼?在目前實踐中和最初的設計有變化嗎?目前通常的用途有哪些?GET 請求GET 請求是 HTTP 協議當中最先出現的請求方法,在 HTTP/0.9 的世界當中,所有的文檔都是只讀的。其設計用途是客戶端請求獲取伺服器的資源。
  • POST請求 報 HTTP status 415 錯誤(postman測試)
    -----------------------------------------------------------------------------415是HTTP協議的狀態碼415的含義是不支持的媒體類型(Unsupported media type)檢查是否在POST請求中加入了
  • 網際網路基礎知識講解:淺談http協議
    http協議工作原理:瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB伺服器發送所有請求,該請求發送到web服務的一個監聽埠上(默認埠是80)。Web伺服器根據接收到的請求後,向客戶端發送響應結果。
  • Java網絡編程——發送HTTP請求到伺服器
    當Java程序需要向伺服器發送請求或讀取伺服器數據時,使用URLConnection類是比較好的選擇。URLConnection類封裝了與伺服器互動操作的方法,通過它可以建立與伺服器的遠程連接,檢查伺服器資源的屬性,向伺服器發送請求並接收伺服器返回的數據。
  • Linux使用epoll控制多個socket發送http請求
    它判斷是否為寫事件,如果是則用getsockopt()讀取錯誤碼,然後填充http請求的緩衝區。最後,設置狀態為連接完成CONNECTED,繼續監控寫事件EPOLLOUT,等待發送數據。因為接下來要發送http請求,這裡還是EPOLLOUT事件。3,client_http_send()為發送函數,在socket可寫時一直寫數據,直到把緩衝區的http請求數據寫完,然後監控socket的讀事件EPOLLIN,等待伺服器的響應。
  • 25、大話HTTP協議-用Wireshark研究一個完整的TCP連接
    TCP將是我們後續需要重點突破的重點,因此前面的文章涉及也不是佷多,暫且看個熱鬧吧!可以看到,這一層最關鍵的信息是埠號,指定了源埠號和目的埠號。是請求報文和響應報文。紅色字體的是請求報文,藍色字體的是響應報文。
  • HTTP系列第1部分-基本概念概述
    ,"active":true,"config":{"url":"http://www.example.com/example","content_type":"json"}}以下是一個GET和一個POST請求的示例。