TCP/IP協(xié)議棧 —— IP、TCP、UDP、HTTP協(xié)議詳解

經(jīng)過面試的同學(xué)經(jīng)常會(huì)遇到這樣的問題: 你是如何理解TCP/IP協(xié)議的?
回答:通訊協(xié)議?三次握手 ? 四次揮手? 一臉懵逼!

如果你感覺已經(jīng)被上述情景安排,那么有必要好好看看這篇文章。

1 、什么是協(xié)議

協(xié)議實(shí)際上就是一種約定。好比說,我們做一個(gè)石頭剪刀布的游戲,我們約定好:石頭>剪刀、剪刀>布、布>石頭,以此作為游戲規(guī)則。我們所有人都遵循這個(gè)約定,那么就不需要任何的多余的溝通便可以完成這個(gè)游戲。而這種方式形成的約定實(shí)際上就是一種協(xié)議了。

2、TCP/IP協(xié)議簇

話聯(lián)網(wǎng)早期時(shí),盡管知道計(jì)算機(jī)連接的原理,但是沒有協(xié)議的時(shí)候,就沒有辦法進(jìn)行大規(guī)模的通信使用。當(dāng)時(shí)就衍生出了很多為了解決當(dāng)時(shí)問題的協(xié)議,像TCP協(xié)議就是為了約定大家使用TCP連接時(shí)傳輸?shù)囊环N協(xié)議,HTTP協(xié)議則是為了約定文本傳輸?shù)囊环N協(xié)議。

而TCP/IP協(xié)議并不是指某一個(gè)具體的協(xié)議,它是指代一系列的協(xié)議棧,因此也叫TCP/IP協(xié)議棧或者TCP/IP協(xié)議簇

所以廣義上,我們說的TCP/IP指的是4層的總和。 而狹義上來說,指的是4層中的傳輸層和網(wǎng)絡(luò)互聯(lián)層。

TCP/IP協(xié)議簇 中,定義了包含對(duì)應(yīng) OSI 模型的每一層。但同時(shí)對(duì) OSI 模型層做了簡(jiǎn)化處理。看看這種圖理解一下:

TCP/IP層和OSI參考模型層的對(duì)應(yīng)關(guān)系

也即是OSI模型中的7層,在TCP/IP中使用4層代替了。沒辦法,誰讓OSI那么復(fù)雜呢。

TCP/IP協(xié)議簇中每一層都有對(duì)應(yīng)的協(xié)議,最終組成協(xié)議簇

TCP/IP協(xié)議棧每一層的協(xié)議

我們經(jīng)常說的TCPUDP在協(xié)議棧的傳輸層,而IP協(xié)議則在協(xié)議棧的網(wǎng)絡(luò)互聯(lián)層。還有經(jīng)常被問到的HTTP協(xié)議實(shí)際上在協(xié)議棧的應(yīng)用層。

TCP/IP協(xié)議棧被分作這么多的層級(jí),目的是為了整理硬件間通信時(shí)的一個(gè)通用的模型,因此它們每一層都和其上下層有關(guān)聯(lián)性的,如下圖:

TCP/IP協(xié)議棧數(shù)據(jù)封包分層

上面就是"TCP/IP協(xié)議"的總體概念了。但是其內(nèi)部還有這么多的協(xié)議,這里挑幾個(gè)常見的講一講,從底層到上層:

  • IP協(xié)議
  • TCP協(xié)議
  • UDP協(xié)議
  • HTTP協(xié)議
2. 1 IP協(xié)議

IP協(xié)議處于TCP/IP協(xié)議簇的網(wǎng)絡(luò)互聯(lián)層。它提供不可靠、無連接的服務(wù),也即依賴其他層的協(xié)議進(jìn)行差錯(cuò)控制。在局域網(wǎng)環(huán)境,IP協(xié)議往往被封裝在以太網(wǎng)幀中傳送。而所有的TCP、UDP、ICMP、IGMP數(shù)據(jù)都被封裝在IP數(shù)據(jù)報(bào)中傳送。

在IP協(xié)議中,有兩個(gè)重要的內(nèi)容需要了解下。一是IP地址的概念,二是IP協(xié)議的報(bào)頭。

2.1.1 IP地址的概念

其實(shí)對(duì)于IP地址我們?nèi)粘=佑|還是挺多的。它給每一個(gè)接入互聯(lián)網(wǎng)的計(jì)算器一個(gè)地址,從而使得其他的計(jì)算機(jī)能夠訪問到它。與此同時(shí),當(dāng)計(jì)算機(jī)有了地址之后,才能遵循IP協(xié)議,和其他的計(jì)算機(jī)進(jìn)行數(shù)據(jù)的傳遞。

目前有兩種IP版本,分別是IPV4和IPV6。IPV4占用8個(gè)字節(jié)32bit,而IPV6則是32個(gè)字節(jié)128bit。IPV6的可用的數(shù)量極其龐大,大到全球每一粒沙子都可以分配一個(gè)IPV6地址。

以IPV4為例, IPV4的32bit地址中,分為兩個(gè)部分:網(wǎng)絡(luò)號(hào)和主機(jī)號(hào)。同時(shí)根據(jù)不同的內(nèi)容開頭,又分為A、B、C、D、E類。

IPV4

網(wǎng)絡(luò)號(hào)用于區(qū)分不同的網(wǎng)絡(luò)點(diǎn),比如一個(gè)公司是一個(gè)網(wǎng)絡(luò)集群,我們可以通過他的網(wǎng)絡(luò)號(hào)確定該公司網(wǎng)關(guān),再通過主機(jī)號(hào)確定每一臺(tái)計(jì)算。

假如一個(gè)C類的IP地址類型,包含了21位網(wǎng)絡(luò)號(hào),實(shí)際上就能區(qū)分出 2^21 個(gè)網(wǎng)絡(luò)號(hào),而在每一個(gè)網(wǎng)絡(luò)號(hào)中,可以區(qū)分 2^8 -2 = 254(起始的網(wǎng)絡(luò)號(hào)地址和最后一個(gè)為廣播地址都不可用于主機(jī))個(gè)主機(jī)號(hào)。如果一個(gè)網(wǎng)吧采用這種方式的話,那么他最多能安裝254臺(tái)機(jī)器。如果我們想要得到更多的主機(jī)號(hào),應(yīng)該延長(zhǎng)主機(jī)號(hào)的位數(shù),但是相應(yīng)的,網(wǎng)絡(luò)號(hào)的數(shù)量將減少,因?yàn)閮烧叩目傞L(zhǎng)度是不變的。

通過掩碼能夠改變網(wǎng)絡(luò)號(hào)和主機(jī)號(hào)的位數(shù)。

通常,我們看到的掩碼類似:

255.255.255.0

二進(jìn)制表示:

11111111.11111111.11111111.00000000

如果一個(gè)IPV4地址為:192.168.1.12
那么IP地址和掩碼經(jīng)過與運(yùn)算之后的結(jié)果為:192.168.1.0(192.168.001.000), 這就是我們常說的網(wǎng)關(guān)!
而從 192.168.1.1~192.168.1.254都可作為主機(jī)號(hào)。也即是這個(gè)網(wǎng)關(guān)下,可以容納 254 臺(tái)機(jī)器。

如果將掩碼更改為:

255.255.254.0

二進(jìn)制表示:

11111111.11111111.11111110.00000000

那么與運(yùn)算的結(jié)果為:192.168.0.0 ,這時(shí)候可以使用的主機(jī)號(hào)就變成了 192.168.0.0 ~ 192.168.1.254, 即可容納 510 臺(tái)機(jī)器。

2.1.2 IP尋址

當(dāng)一個(gè) IP 包從一臺(tái)計(jì)算機(jī)被發(fā)送,它會(huì)到達(dá)一個(gè) IP 路由器。

IP 路由器負(fù)責(zé)將這個(gè)包路由至它的目的地,直接地或者通過其他的路由器。

在一個(gè)相同的通信中,一個(gè)包所經(jīng)由的路徑可能會(huì)和其他的包不同。而路由器負(fù)責(zé)根據(jù)通信量、網(wǎng)絡(luò)中的錯(cuò)誤或者其他參數(shù)來進(jìn)行正確地尋址。

2.1.3 IP協(xié)議的報(bào)頭

在上面的數(shù)據(jù)分層中,我們看到IP協(xié)議的構(gòu)成實(shí)際上是 IP報(bào)頭 + TCP協(xié)議內(nèi)容。

因此決定一個(gè)IP協(xié)議屬性的的關(guān)鍵是 IP報(bào)頭的內(nèi)容。
下面我們來看下IP協(xié)議的組成,IPV4中普通的IP首部長(zhǎng)20個(gè)字節(jié)。其中有32位的源IP地址和32位的目的IP地址。

TTL:生存時(shí)間。代表了數(shù)據(jù)包可以經(jīng)過的最多路由器數(shù)。比如TTL為10,意思是如果經(jīng)過10次路由器轉(zhuǎn)發(fā),仍然未找到目的地址,則報(bào)文丟棄

8位協(xié)議指示的是傳輸層承載的協(xié)議

16位總長(zhǎng)度:指IP數(shù)據(jù)包的最大長(zhǎng)度。16bit那么最長(zhǎng)可達(dá)65535字節(jié)。但是通過鏈路的MTU不會(huì)有這么大。因此如果數(shù)據(jù)包長(zhǎng)度超過了MTU,數(shù)據(jù)包會(huì)被分片。如果發(fā)生了分片,則需要用到16位標(biāo)識(shí)以及13位片偏移來找到分片的報(bào)文。

IP協(xié)議報(bào)頭
2.2 TCP協(xié)議
2.2.1 TCP協(xié)議作用

TCP協(xié)議位于協(xié)議棧的傳輸層。當(dāng)應(yīng)用層向TCP層發(fā)送用于網(wǎng)間傳輸?shù)摹⒂?位字節(jié)表示的數(shù)據(jù)流,TCP則把數(shù)據(jù)流分割成適當(dāng)長(zhǎng)度的報(bào)文段,最大傳輸段大小(MSS)通常受該計(jì)算機(jī)連接的網(wǎng)絡(luò)的數(shù)據(jù)鏈路層的最大傳送單元(MTU)限制。之后TCP把數(shù)據(jù)包傳給IP層,由它來通過網(wǎng)絡(luò)將包傳送給接收端實(shí)體的TCP層。

TCP為了保證報(bào)文傳輸?shù)目煽浚徒o每個(gè)包一個(gè)序號(hào),同時(shí)序號(hào)也保證了傳送到接收端實(shí)體的包的按序接收。然后接收端實(shí)體對(duì)已成功收到的字節(jié)發(fā)回一個(gè)相應(yīng)的確認(rèn)(ACK);如果發(fā)送端實(shí)體在合理的往返時(shí)延(RTT)內(nèi)未收到確認(rèn),那么對(duì)應(yīng)的數(shù)據(jù)(假設(shè)丟失了)將會(huì)被重傳。

  • 在數(shù)據(jù)正確性與合法性上,TCP用一個(gè)校驗(yàn)和函數(shù)來檢驗(yàn)數(shù)據(jù)是否有錯(cuò)誤,在發(fā)送和接收時(shí)都要計(jì)算校驗(yàn)和;同時(shí)可以使用md5認(rèn)證對(duì)數(shù)據(jù)進(jìn)行加密。

  • 在保證可靠性上,采用超時(shí)重傳和捎帶確認(rèn)機(jī)制。

  • 在流量控制上,采用滑動(dòng)窗口協(xié)議,協(xié)議中規(guī)定,對(duì)于窗口內(nèi)未經(jīng)確認(rèn)的分組需要重傳。

在擁塞控制上,采用廣受好評(píng)的TCP擁塞控制算法(也稱AIMD算法)。
該算法主要包括三個(gè)主要部分:
(1)加性增、乘性減;
(2)慢啟動(dòng);
(3)對(duì)超時(shí)事件做出反應(yīng)。

2.2.2 TCP的報(bào)頭

和IP協(xié)議一樣,TCP協(xié)議也有他的報(bào)頭部分。
以下即是圖示:


TCP報(bào)頭
  • 源端口:發(fā)送方的端口號(hào)
  • 目的端口:接受方的端口號(hào)
  • 序號(hào):發(fā)送方的序號(hào)
  • 確認(rèn)序號(hào):接受方得到序號(hào)之后回復(fù)的確認(rèn)序號(hào)
  • TCP 首部長(zhǎng)度:4 bits,以32-bit字為單位。TCP首部長(zhǎng)短,也是TCP報(bào)文數(shù)據(jù)部分的偏移量。范圍5~15,即20 bytes ~ 60 bytes。可選項(xiàng)部分最多允許40 bytes。

標(biāo)志位,標(biāo)志位主要用戶標(biāo)志該報(bào)文當(dāng)前的狀態(tài)。

  • URG:指示報(bào)文中有緊急數(shù)據(jù),應(yīng)盡快傳送(相當(dāng)于高優(yōu)先級(jí)的數(shù)據(jù))。
  • ACK:確認(rèn)序號(hào)(AN)有效。
  • PSH:接到后盡快交付給接收的應(yīng)用進(jìn)程。
  • RST:TCP連接中出現(xiàn)嚴(yán)重差錯(cuò)(如主機(jī)崩潰),必須釋放連接,在重新建立連接。
  • SYN:處于TCP連接建立過程。
  • FIN:發(fā)送端已完成數(shù)據(jù)傳輸,請(qǐng)求釋放連接。
2.2.2 TCP協(xié)議的連接時(shí)候的三次握手

TCP是一個(gè)面向連接的協(xié)議,在每一次傳輸數(shù)據(jù)前,客戶端和服務(wù)端需要進(jìn)行連接,這個(gè)鏈接就是著名的三次握手。

第一次:客戶端向服務(wù)端發(fā)送一個(gè) SYN(SEQ=x 客戶端序號(hào))報(bào)文給服務(wù)器端,進(jìn)入SYN_SEND狀態(tài)。

第二次:服務(wù)器端收到SYN報(bào)文,回應(yīng)一個(gè)SYN (SEQ=y 服務(wù)端序號(hào))ACK(ACK=x+1 確認(rèn)號(hào)=客戶端序號(hào)+1)報(bào)文,進(jìn)入SYN_RECV狀態(tài)。

第三次:客戶端收到服務(wù)器端的SYN報(bào)文,回應(yīng)一個(gè)ACK(ACK=y+1)報(bào)文,進(jìn)入Established狀態(tài)。

圖解:


TCP的三次握手

思考:為什么要進(jìn)行三次握手,而不是兩次呢? 比如在第一次握手之后,服務(wù)器進(jìn)入準(zhǔn)備狀態(tài),然后發(fā)送消息給客戶端,客戶端也進(jìn)入準(zhǔn)備狀態(tài),這就完成了雙方的確認(rèn)了。

  • 回答:兩次握手時(shí),服務(wù)器提前進(jìn)入準(zhǔn)備狀態(tài)之后,如果中途遇到網(wǎng)絡(luò)中斷,消息并沒有傳回給客戶端,客戶端將永遠(yuǎn)接不到服務(wù)器的給入狀態(tài),那么服務(wù)端將資源浪費(fèi)在一個(gè)不存在的連接之上了。

思考2:三次握手就很安全了嗎?

  • 回答:在三次握手過程中,Server發(fā)送SYN-ACK之后,收到Client的ACK之前的TCP連接稱為半連接(half-open connect),此時(shí)Server處于SYN_RCVD狀態(tài),當(dāng)收到ACK后,Server轉(zhuǎn)入ESTABLISHED狀態(tài)。SYN攻擊就是Client在短時(shí)間內(nèi)偽造大量不存在的IP地址,并向Server不斷地發(fā)送SYN包,Server回復(fù)確認(rèn)包,并等待Client的確認(rèn),由于源地址是不存在的,因此,Server需要不斷重發(fā)直至超時(shí),這些偽造的SYN包將產(chǎn)時(shí)間占用未連接隊(duì)列,導(dǎo)致正常的SYN請(qǐng)求因?yàn)殛?duì)列滿而被丟棄,從而引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓。SYN攻擊時(shí)一種典型的DDOS攻擊,檢測(cè)SYN攻擊的方式非常簡(jiǎn)單,即當(dāng)Server上有大量半連接狀態(tài)且源IP地址是隨機(jī)的,則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現(xiàn)行:
#netstat -nap | grep SYN_RECV
2.2.3 TCP協(xié)議的斷開連接時(shí)候的四次揮手

既然TCP面向連接,那么肯定也有斷開連接的操作。一個(gè)TCP完整的斷開需要進(jìn)行四次揮手。

第一次:客戶端向服務(wù)端發(fā)送 FIN + ACK 報(bào)文,同時(shí)攜帶序號(hào)為 X。 客戶端進(jìn)入 FIN-WAIT1

第二次:服務(wù)器端回復(fù) ACK 報(bào)文。附帶序號(hào)Z和確認(rèn)序號(hào)X+1,表示服務(wù)器已經(jīng)接受到了客服端的報(bào)文。但是由于服務(wù)器可能還在處理事務(wù),因此,報(bào)文并不會(huì)攜帶FIN標(biāo)志。狀態(tài):CLOSE WAIT

第三次:在一段時(shí)間之后,服務(wù)器已經(jīng)處理完畢,發(fā)送帶有 FIN和ACK的報(bào)文,序號(hào)為Y,確認(rèn)序號(hào)為 X + 1 。 狀態(tài): ACK-LAST

第四次:客戶端發(fā)送ACK報(bào)文,序號(hào)為 X+1,確認(rèn)號(hào)Y+1 。 客戶端進(jìn)入: TIME_WAIT。服務(wù)端進(jìn)圖CLOSE(初始狀態(tài))

TCP四次揮手

思考:為什么建立連接是三次握手,而關(guān)閉連接卻是四次揮手呢?

  • 回答:這是因?yàn)榉?wù)端在LISTEN狀態(tài)下,收到建立連接請(qǐng)求的SYN報(bào)文后,把ACK和SYN放在一個(gè)報(bào)文里發(fā)送給客戶端。而關(guān)閉連接時(shí),當(dāng)收到對(duì)方的FIN報(bào)文時(shí),僅僅表示對(duì)方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù),己方也未必全部數(shù)據(jù)都發(fā)送給對(duì)方了,所以己方可以立即close,也可以發(fā)送一些數(shù)據(jù)給對(duì)方后,再發(fā)送FIN報(bào)文給對(duì)方來表示同意現(xiàn)在關(guān)閉連接,因此,己方ACK和FIN一般都會(huì)分開發(fā)送。

思考:為什么TIME_WAIT狀態(tài)需要經(jīng)過2MSL(最大報(bào)文段生存時(shí)間)才能返回到CLOSE狀態(tài)?

  • 原因有二:
    一、保證TCP協(xié)議的全雙工連接能夠可靠關(guān)閉
    二、保證這次連接的重復(fù)數(shù)據(jù)段從網(wǎng)絡(luò)中消失
2.3 UDP協(xié)議

UDP協(xié)議全稱是用戶數(shù)據(jù)報(bào)協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,兩者同處于協(xié)議棧的傳輸層,和TCP不同的是,UDP是一種無連接的協(xié)議。

因?yàn)閁DP是無連接的,所以相對(duì)來說,UDP的報(bào)頭比TCP要簡(jiǎn)單多了。


UDP報(bào)頭

UDP 特點(diǎn)
(1) UDP是一個(gè)非連接的協(xié)議,傳輸數(shù)據(jù)之前源端和終端不建立連接,當(dāng)它想傳送時(shí)就簡(jiǎn)單地去抓取來自應(yīng)用程序的數(shù)據(jù),并盡可能快地把它扔到網(wǎng)絡(luò)上。在發(fā)送端,UDP傳送數(shù)據(jù)的速度僅僅是受應(yīng)用程序生成數(shù)據(jù)的速度、計(jì)算機(jī)的能力和傳輸帶寬的限制;在接收端,UDP把每個(gè)消息段放在隊(duì)列中,應(yīng)用程序每次從隊(duì)列中讀一個(gè)消息段。
(2) 由于傳輸數(shù)據(jù)不建立連接,因此也就不需要維護(hù)連接狀態(tài),包括收發(fā)狀態(tài)等,因此一臺(tái)服務(wù)機(jī)可同時(shí)向多個(gè)客戶機(jī)傳輸相同的消息。
(3) UDP信息包的標(biāo)題很短,只有8個(gè)字節(jié),相對(duì)于TCP的20個(gè)字節(jié)信息包的額外開銷很小。
(4) 吞吐量不受擁擠控制算法的調(diào)節(jié),只受應(yīng)用軟件生成數(shù)據(jù)的速率、傳輸帶寬、源端和終端主機(jī)性能的限制。
(5)UDP使用盡最大努力交付,即不保證可靠交付,因此主機(jī)不需要維持復(fù)雜的鏈接狀態(tài)表(這里面有許多參數(shù))。
(6)UDP是面向報(bào)文的。發(fā)送方的UDP對(duì)應(yīng)用程序交下來的報(bào)文,在添加首部后就向下交付給IP層。既不拆分,也不合并,而是保留這些報(bào)文的邊界,因此,應(yīng)用程序需要選擇合適的報(bào)文大小。

我們經(jīng)常使用“ping”命令來測(cè)試兩臺(tái)主機(jī)之間TCP/IP通信是否正常,其實(shí)“ping”命令的原理就是向?qū)Ψ街鳈C(jī)發(fā)送UDP數(shù)據(jù)包,然后對(duì)方主機(jī)確認(rèn)收到數(shù)據(jù)包,如果數(shù)據(jù)包是否到達(dá)的消息及時(shí)反饋回來,那么網(wǎng)絡(luò)就是通的。

2.4 HTTP協(xié)議

HTTP協(xié)議名為超文本傳輸協(xié)議。這個(gè)協(xié)議在 TCP/IP 協(xié)議棧的應(yīng)用層,因此我們無需操心HTTP是如何傳輸?shù)模恍枰P(guān)心,我們傳輸?shù)膬?nèi)容,能否正確的被接收端識(shí)別。

HTTP 基于TCP實(shí)現(xiàn),簡(jiǎn)單來說,TCP協(xié)議負(fù)責(zé)可靠的內(nèi)容傳輸,HTTP協(xié)議負(fù)責(zé)識(shí)別內(nèi)容,兩者本身不在一個(gè)層面,沒有可比行。

HTTP無狀態(tài)的意思是,每一次的內(nèi)容解析是沒有關(guān)聯(lián)的。TCP有狀態(tài)是指兩端在連接過程的。

HTTP包含兩種報(bào)文類型:請(qǐng)求報(bào)文、響應(yīng)報(bào)文。請(qǐng)求報(bào)文用在客戶端對(duì)服務(wù)器的請(qǐng)求時(shí)使用的報(bào)文格式,響應(yīng)用在服務(wù)器響應(yīng)請(qǐng)求的報(bào)文格式。

2.4.1 HTTP協(xié)議請(qǐng)求消息結(jié)構(gòu)

客戶端發(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器的請(qǐng)求消息包括以下格式:請(qǐng)求行(request line)、請(qǐng)求頭部(header)、空行和請(qǐng)求數(shù)據(jù)四個(gè)部分組成,下圖給出了請(qǐng)求報(bào)文的一般格式。

HTTP請(qǐng)求消息體結(jié)構(gòu)

HTTP消息體主要包含以下實(shí)質(zhì)內(nèi)容(空格和換行也必不可少):

  • 請(qǐng)求方法
  • URL:統(tǒng)一資源定位符
  • HTTP請(qǐng)求頭部
  • HTTP請(qǐng)求體

以下是一個(gè)HTTP請(qǐng)求的例子:


HTTP請(qǐng)求實(shí)例
2.4.1.1 HTTP請(qǐng)求方法

HTTP包含了多種不同的請(qǐng)求方式,每一種請(qǐng)求方式用在不同的場(chǎng)景。

HTTP請(qǐng)求方法
2.4.1.2 URL —— 統(tǒng)一資源定位符

URL由三部分組成:資源類型、存放資源的主機(jī)域名、資源文件名。
URL的一般語法格式為:
(帶方括號(hào)[]的為可選項(xiàng)):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
舉個(gè)例子: https://baijiahao.baidu.com/s?id=1603848351636567407&wfr=spider&for=pc

protocol:https
hostname:baijiahao.baidu.com
parameters:id=1603848351636567407&wfr=spider&for=pc (使用&分割參數(shù))

總結(jié)一下如下圖:

附一張解析圖
2.4.1.3 HTTP請(qǐng)求頭

請(qǐng)求頭中主要包含本次請(qǐng)求的附加信息,其中常用的字段如:

  • Accept: 指定客戶端能夠接收的內(nèi)容類型
  • Accept-Encoding: 指定瀏覽器可以支持的web服務(wù)器返回內(nèi)容壓縮編碼類型。
  • Accept-Language: 瀏覽器可接受的語言
  • Content-Length 請(qǐng)求的內(nèi)容長(zhǎng)度 如:Content-Length: 348
  • Content-Type 請(qǐng)求的與實(shí)體對(duì)應(yīng)的MIME信息,常用的類型


    image.png
  • Date 請(qǐng)求發(fā)送的日期和時(shí)間
    更多的請(qǐng)求頭字段參考 HTTP響應(yīng)頭和請(qǐng)求頭信息對(duì)照表
2.4.1.4 HTTP請(qǐng)求體

在整個(gè)報(bào)文中,請(qǐng)求頭之后,隔一行空格,以下部分就是HTTP的請(qǐng)求體了。
請(qǐng)求體是我們發(fā)送請(qǐng)求的時(shí)候需要傳給接收端的內(nèi)容。其格式需要和請(qǐng)求頭中的Content-Type對(duì)應(yīng)。不然會(huì)導(dǎo)致接受無法識(shí)別。
如上圖中的請(qǐng)求體: name=tom&password=1234

2.4.2 HTTP響應(yīng)

HTTP的響應(yīng)同樣分為:響應(yīng)行、響應(yīng)頭、響應(yīng)體。和請(qǐng)求報(bào)文有點(diǎn)類似。
總體結(jié)構(gòu)如圖:


HTTP響應(yīng)報(bào)文
2.4.2.1 HTTP響應(yīng)行

響應(yīng)行中包含了HTTP的版本和本次請(qǐng)求的狀態(tài)。請(qǐng)求狀態(tài)的對(duì)應(yīng)值見 HTTP響應(yīng)碼大全.

2.4.2.2 HTTP響應(yīng)頭

響應(yīng)頭用于描述服務(wù)器的基本信信息、數(shù)據(jù)的描述,這些信息將告知客戶端如何處理響應(yīng)題中的內(nèi)容。

  • Allow 服務(wù)器支持哪些請(qǐng)求方法(如GET、POST等)。
  • Content-Encoding 文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內(nèi)容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時(shí)間。Java的GZIPOutputStream可以很方便地進(jìn)行g(shù)zip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應(yīng)該通過查看Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經(jīng)gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。
  • Content-Length 表示內(nèi)容長(zhǎng)度。只有當(dāng)瀏覽器使用持久HTTP連接時(shí)才需要這個(gè)數(shù)據(jù)。如果你想要利用持久連接的優(yōu)勢(shì),可以把輸出文檔寫入 ByteArrayOutputStream,完成后查看其大小,然后把該值放入Content-Length頭,最后通過byteArrayStream.writeTo(response.getOutputStream()發(fā)送內(nèi)容。
  • Content-Type 表示后面的文檔屬于什么MIME類型。Servlet默認(rèn)為text/plain,但通常需要顯式地指定為text/html。由于經(jīng)常要設(shè)置Content-Type,因此HttpServletResponse提供了一個(gè)專用的方法setContentType。
    更多的響應(yīng)頭字段參考 HTTP響應(yīng)頭和請(qǐng)求頭信息對(duì)照表
2.4.2.3 HTTP響應(yīng)實(shí)體

響應(yīng)實(shí)體中包含的就是客戶端從服務(wù)器中獲取的數(shù)據(jù)了。數(shù)據(jù)的格式和長(zhǎng)度都會(huì)在響應(yīng)體頭中描述。

3. 更多的內(nèi)容

除了 TCP/IP 協(xié)議棧的內(nèi)容之外,還要諸如 ScoketHTTPS 協(xié)議等內(nèi)容沒有再本文中介紹。主要是因?yàn)槠渌膬?nèi)容相對(duì)來說形成一套體系,內(nèi)容較多,將會(huì)在后續(xù)的文章中介紹。

后續(xù):HTTPS協(xié)議的實(shí)現(xiàn)原理

參考:
TCP/IP四層模型
TCP/IP協(xié)議之IP層
TCP協(xié)議與UDP協(xié)議的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,346評(píng)論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評(píng)論 0 286
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,558評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,739評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,980評(píng)論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評(píng)論 1 280
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,347評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,702評(píng)論 2 370