圖解TCP/IP詳解(史上最全)
一、OSI參考模型
1.圖示
2.OSI七層模型各自作用
應用層
為應用程序提供服務並規定應用程序中通信的相關細節。包括文件傳輸、電子郵件、遠程登錄等協議。
表示層
將應用處理的信息轉換為適合網絡傳輸的格式,或將來自下一層的數據轉換為上層能夠處理的格式。因此它主要負責數據格式的轉換。
會話層
負責建立和斷開通信連接(數據流動的邏輯通路),以及數據的分割等數據傳輸相關的管理。
傳輸層
起着可靠傳輸的作用。只在通信雙方節點上進行處理,而無需在路由器上處理。會話層負責決定建立連接和斷開連接的時機,而傳輸層進行實際的建立和斷開處理
網絡層
將數據傳輸到目標地址。目標地址可以是多個網絡通過路由器連接而成的某個地址。因此這一層主要負責尋址和路由選擇
數據鏈路層
負責物理層上的互聯、節點之間的通信傳輸。例如與1個以太網相連的2個節點之間的通信。將0、1序列划分為具有意義的數據幀傳送給對端(數據幀的生成與接收)。
物理層
負責0、1比特流(0、1序列)與電壓的高低、光的閃滅之間的互換
3.七層通信過程
二、IP協議
1.IPv4首部
- 版本:表示 IP 協議的版本。
- 首部長度:首部的長度,單位是 4 字節。
- 區分服務:暫時無意義。
- 總長度:首部和數據之和的長度,單位為字節,當數據報的總長度超過數據鏈路層的最大傳送單元時就必須進行分片處理。將一個 IP 數據報分成多個分片,每個分片都具有 IP 首部。
- 標識:對分片進行標識,同一個數據報的分片具有同樣的標識。
- 標志:占 3 位。最低位記為 MF(More Fragment),MF = 1 表示后面“還有分片”,MF = 0 表示這是多個數據報片中的最后一個;中間一位記為 DF(Don't Fragment),只有當 DF = 0 時才允許分片。
- 片偏移:表示該分片在原分組中的相對位置,片偏移以 8 個字節為偏移單位。
- 生存時間:TTL,表示該數據報在網絡中可以被轉發的次數,每經過一次轉發,這個值減 1。
- 首部校驗和:這個字段只檢驗數據報的首部,不檢驗數據部分。
- 源地址
- 目的地址
- 可變部分:可變部分中包括用於增加 IP 數據報功能的選項,這些選項一個一個拼起來,中間不需要分隔符,最后用 0 填充為 4 字節的整數倍。
WireShark抓包的情況
可以看到首部長度值為5行,20bytes(5行*4字節每行=20字節)
首部長度是4bit,而2^4是16,所以它的取值范圍是0-15(也可理解為4bit即是4個1,轉換成十進制就是15),圖中每行是4個字節(32bits),所以最大長度就是15*4=60字節。
2.IPv6首部
- 版本:協議的版本,對於 IPv6 是 6.
- 流標號:“流”指互聯網絡上從特定源點到特定終點的一系列數據報,所有屬於同一個流的數據報都具有同樣的流標號。
- 有效載荷長度:表示 IPv6 數據報除基本首部以外的字節數。
- 下一個首部:當沒有擴展首部時,下一個首部字段指出基本首部后面的數據應該移交給哪個高層協議。當出現擴展首部時,下一個首部字段的值表示后面第一個擴展首部的類型。
- 數據報圖中經過的路由器不處理擴展首部。
- IPv6 采用冒號十六進制記法,如 68E6:8C64:FFFF:FFFF:0:1180:960A:FFFF,冒號十六進制記法允許零壓縮,即一連串連續的零可以為一對冒號所取代,任一地址中只能夠使用一次零壓縮。
三、TCP協議
面向連接,提供可靠的服務,有流量控制,擁塞控制,無重復、無丟失、無差錯,面向字節流(把應用層傳下來的報文看成字節流,把字節流組織成大小不等的數據塊),只能是點對點,首部 20 字節,全雙工
1.tcp首部格式
- 序號 :用於對字節流進行編號,例如序號為 301,表示第一個字節的編號為 301,如果攜帶的數據長度為 100 字節,那么下一個報文段的序號應為 401。
- 確認號 :期望收到的下一個報文段的序號。例如 B 正確收到 A 發送來的一個報文段,序號為 501,攜帶的數據長度為 200 字節,因此 B 期望下一個報文段的序號為 701,B 發送給 A 的確認報文段中確認號就為 701。
- 數據偏移 :指的是數據部分距離報文段起始處的偏移量,實際上指的是首部的長度。
- 確認 ACK :當 ACK=1 時確認號字段有效,否則無效。TCP 規定,在連接建立后所有傳送的報文段都必須把 ACK 置 1。
- 同步 SYN :在連接建立時用來同步序號。當 SYN=1,ACK=0 時表示這是一個連接請求報文段。若對方同意建立連接,則響應報文中 SYN=1,ACK=1。
- 終止 FIN :用來釋放一個連接,當 FIN=1 時,表示此報文段的發送方的數據已發送完畢,並要求釋放運輸連接。
- 窗口 :窗口值作為接收方讓發送方設置其發送窗口的依據。之所以要有這個限制,是因為接收方的數據緩存空間是有限的。
TCP連接:SYN ACK RST UTG PSH FIN
SYN:同步標志
同步序列編號(Synchronize Sequence Numbers)欄有效。該標志僅在三次握手建立TCP連接時有效。它提示TCP連接的服務端檢查序列編號,該序列編號為TCP連接初始端(一般是客戶端)的初始序列編號。
ACK:確認標志
確認編號(Acknowledgement Number)欄有效。大多數情況下該標志位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure-1)為下一個預期的序列編號,同時提示遠端系統已經成功接收所有數據。
RST:復位標志
復位標志有效。用於復位相應的TCP連接。
URG:緊急標志
緊急(The urgent pointer) 標志有效。緊急標志置位,
PSH:推標志
該標志置位時,接收端不將該數據進行隊列處理,而是盡可能快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的連接時,該標志總是置位的。
FIN:結束標志
帶有該標志置位的數據包用來結束一個TCP回話,但對應端口仍處於開放狀態,准備接收后續數據。
在TCP層,有個FLAGS字段,這個字段有以下幾個標識:SYN, FIN, ACK, PSH, RST, URG.其中,對於我們日常的分析有用的就是前面的五個字段。它們的含義是:SYN表示建立連接,FIN表示關閉連接,ACK表示響應,PSH表示有 DATA數據傳輸,RST表示連接重置。
其中,ACK是可能與SYN,FIN等同時使用的,比如SYN和ACK可能同時為1,它表示的就是建立連接之后的響應,如果只是單個的一個SYN,它表示的只是建立連接。
TCP的幾次握手就是通過這樣的ACK表現出來的。但SYN與FIN是不會同時為1的,因為前者表示的是建立連接,而后者表示的是斷開連接。
RST一般是在FIN之后才會出現為1的情況,表示的是連接重置。一般地,當出現FIN包或RST包時,我們便認為客戶端與服務器端斷開了連接;
而當出現SYN和SYN+ACK包時,我們認為客戶端與服務器建立了一個連接。
PSH為1的情況,一般只出現在DATA內容不為0的包中,也就是說PSH為1表示的是有真正的TCP數據包內容被傳遞。TCP的連接建立和連接關閉,都是通過請求-響應的模式完成的。
WireShark抓包的情況
其中目的端口為0885(16進制),轉換成10進制就為2181
2.握手揮手圖示
3.握手流程
第一次握手: 建立連接。客戶端發送連接請求報文段,將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三次握手。
4.為什么要三次握手?
為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。
具體例子:“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。”
5.四次揮手流程
客戶端正常斷開:
服務器端殺掉進程:
從抓包信息看是服務器的一個流量控制機制啟動了。服務器發回rst位,同時win置為0,是告訴客戶端不要發包。按tcp流控機制來說,此時客戶端應該停止發包,直至服務器發送信息告訴客戶端可以繼續發送,從圖中可以看到,客戶端的請求重傳了兩次,如果還是失敗會創建新的syn包繼續嘗試連接。
揮手流程:
第一次分手: 主機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也可以關閉連接了。
上圖中服務器發回rst位,同時win置為0,是告訴客戶端不要發包。按tcp流控機制來說,此時客戶端應該停止發包,直至服務器發送信息告訴客戶端可以繼續發送。
6.為什么要四次分手?
TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP是全雙工模式,這就意味着,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2,它的數據已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的數據;當主機2返回ACK報文段時,表示它已經知道主機1沒有數據發送了,但是主機2還是可以發送數據到主機1的;當主機2也發送了FIN報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,之后彼此就會愉快的中斷這次TCP連接。
7.為什么要等待2MSL?
MSL:報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間。
原因有二:
保證TCP協議的全雙工連接能夠可靠關閉
保證這次連接的重復數據段從網絡中消失
第一點:如果主機1直接CLOSED了,那么由於IP協議的不可靠性或者是其它網絡原因,導致主機2沒有收到主機1最后回復的ACK。那么主機2就會在超時之后繼續發送FIN,此時由於主機1已經CLOSED了,就找不到與重發的FIN對應的連接。所以,主機1不是直接進入CLOSED,而是要保持TIME_WAIT,當再次收到FIN的時候,能夠保證對方收到ACK,最后正確的關閉連接。
第二點:如果主機1直接CLOSED,然后又再向主機2發起一個新連接,我們不能保證這個新連接與剛關閉的連接的端口號是不同的。也就是說有可能新連接和老連接的端口號是相同的。一般來說不會發生什么問題,但是還是有特殊情況出現:假設新連接和已經關閉的老連接端口號是一樣的,如果前一次連接的某些數據仍然滯留在網絡中,這些延遲數據在建立新連接之后才到達主機2,由於新連接和老連接的端口號是一樣的,TCP協議就認為那個延遲的數據是屬於新連接的,這樣就和真正的新連接的數據包發生混淆了。所以TCP連接還要在TIME_WAIT狀態等待2倍MSL,這樣可以保證本次連接的所有數據都從網絡中消失。
8.TCP流量控制
如果發送方把數據發送得過快,接收方可能會來不及接收,這就會造成數據的丟失。所謂流量控制就是讓發送方的發送速率不要太快,要讓接收方來得及接收。
利用滑動窗口機制可以很方便地在TCP連接上實現對發送方的流量控制。
設A向B發送數據。在連接建立時,B告訴了A:“我的接收窗口是 rwnd = 400 ”(這里的 rwnd 表示 receiver window) 。因此,發送方的發送窗口不能超過接收方給出的接收窗口的數值。請注意,TCP的窗口單位是字節,不是報文段。假設每一個報文段為100字節長,而數據報文段序號的初始值設為1。大寫ACK表示首部中的確認位ACK,小寫ack表示確認字段的值ack。
從圖中可以看出,B進行了三次流量控制。第一次把窗口減少到 rwnd = 300 ,第二次又減到了 rwnd = 100 ,最后減到 rwnd = 0 ,即不允許發送方再發送數據了。這種使發送方暫停發送的狀態將持續到主機B重新發出一個新的窗口值為止。B向A發送的三個報文段都設置了 ACK = 1 ,只有在ACK=1時確認號字段才有意義。
TCP為每一個連接設有一個持續計時器(persistence timer)。只要TCP連接的一方收到對方的零窗口通知,就啟動持續計時器。若持續計時器設置的時間到期,就發送一個零窗口控測報文段(攜1字節的數據),那么收到這個報文段的一方就重新設置持續計時器。
9.TCP擁塞控制
慢開始和擁塞避免
發送方維持一個擁塞窗口 cwnd ( congestion window )的狀態變量。擁塞窗口的大小取決於網絡的擁塞程度,並且動態地在變化。發送方讓自己的發送窗口等於擁塞窗口。
發送方控制擁塞窗口的原則是:只要網絡沒有出現擁塞,擁塞窗口就再增大一些,以便把更多的分組發送出去。但只要網絡出現擁塞,擁塞窗口就減小一些,以減少注入到網絡中的分組數。
慢開始算法
當主機開始發送數據時,如果立即所大量數據字節注入到網絡,那么就有可能引起網絡擁塞,因為現在並不清楚網絡的負荷情況。
因此,較好的方法是 先探測一下,即由小到大逐漸增大發送窗口,也就是說,由小到大逐漸增大擁塞窗口數值。
通常在剛剛開始發送報文段時,先把擁塞窗口 cwnd 設置為一個最大報文段MSS的數值。而在每收到一個對新的報文段的確認后,把擁塞窗口增加至多一個MSS的數值。用這樣的方法逐步增大發送方的擁塞窗口 cwnd ,可以使分組注入到網絡的速率更加合理。
每經過一個傳輸輪次,擁塞窗口 cwnd 就加倍。一個傳輸輪次所經歷的時間其實就是往返時間RTT。不過“傳輸輪次”更加強調:把擁塞窗口cwnd所允許發送的報文段都連續發送出去,並收到了對已發送的最后一個字節的確認。
另,慢開始的“慢”並不是指cwnd的增長速率慢,而是指在TCP開始發送報文段時先設置cwnd=1,使得發送方在開始時只發送一個報文段(目的是試探一下網絡的擁塞情況),然后再逐漸增大cwnd。
為了防止擁塞窗口cwnd增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量。慢開始門限ssthresh的用法如下:
當 cwnd < ssthresh 時,使用上述的慢開始算法。
當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法。
當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法。
擁塞避免
讓擁塞窗口cwnd緩慢地增大,即每經過一個往返時間RTT就把發送方的擁塞窗口cwnd加1,而不是加倍。這樣擁塞窗口cwnd按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多。
無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認),就要把慢開始門限ssthresh設置為出現擁塞時的發送方窗口值的一半(但不能小於2)。然后把擁塞窗口cwnd重新設置為1,執行慢開始算法。
這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生 擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。
如下圖,用具體數值說明了上述擁塞控制的過程。現在發送窗口的大小和擁塞窗口一樣大。
2.快重傳和快恢復
快重傳
快重傳算法首先要求接收方每收到一個失序的報文段后就立即發出重復確認(為的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時才進行捎帶確認。
接收方收到了M1和M2后都分別發出了確認。現在假定接收方沒有收到M3但接着收到了M4。
顯然,接收方不能確認M4,因為M4是收到的失序報文段。根據 可靠傳輸原理,接收方可以什么都不做,也可以在適當時機發送一次對M2的確認。
但按照快重傳算法的規定,接收方應及時發送對M2的重復確認,這樣做可以讓 發送方及早知道報文段M3沒有到達接收方。發送方接着發送了M5和M6。接收方收到這兩個報文后,也還要再次發出對M2的重復確認。這樣,發送方共收到了 接收方的四個對M2的確認,其中后三個都是重復確認。
快重傳算法還規定,發送方只要一連收到三個重復確認就應當立即重傳對方尚未收到的報文段M3,而不必 繼續等待M3設置的重傳計時器到期。
由於發送方盡早重傳未被確認的報文段,因此采用快重傳后可以使整個網絡吞吐量提高約20%。
快恢復
與快重傳配合使用的還有快恢復算法,其過程有以下兩個要點:
當發送方連續收到三個重復確認,就執行“乘法減小”算法,把慢開始門限ssthresh減半。
與慢開始不同之處是現在不執行慢開始算法(即擁塞窗口cwnd現在不設置為1),而是把cwnd值設置為 慢開始門限ssthresh減半后的數值,然后開始執行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。
四、UDP協議
UDP(User Data Protocol,用戶數據報協議)是一個非連接的協議,傳輸數據之前源端和終端不建立連接,當它想傳送時就簡單地去抓取來自應用程序的數據,並盡可能快地把它扔到網絡上。在發送端,UDP傳送數據的速度僅僅是受應用程序生成數據的速度、計算機的能力和傳輸帶寬的限制。
1.UDP首部格式
首部字段只有 8 個字節,包括源端口、目的端口、長度、檢驗和。12 字節的偽首部是為了計算檢驗和臨時添加的。
五、HTTP協議
1.http請求報文
2.http響應報文
3.method: 請求方法,標明客戶端希望服務器對資源執行的動作
- GET:從服務器獲取一個資源
- HEAD:只從服務器獲取文檔的響應首部
- POST:向服務器輸入數據,通常會再由網關程序繼續處理
- PUT:將請求的主體部分存儲在服務器中,如上傳文件
- DELETE:請求刪除服務器上指定的文檔
- TRACE:追蹤請求到達服務器中間經過的代理服務器
- OPTIONS:請求服務器返回對指定資源支持使用的請求方法
4.status:標記請求處理過程中發生的情況,如200,301, 302, 404, 502
- 200: 成功,請求數據通過響應報文的entity-body部分發送;OK
- 301: 請求的URL指向的資源已經被刪除;但在響應報文中通過首部Location指明了資源現在所處的新位置;Moved Permanently
- 302: 響應報文Location指明資源臨時新位置;Moved Temporarily
- 304: 客戶端發出了條件式請求,但服務器上的資源未曾發生改變,則通過響應此響應狀態碼通知客戶端;Not Modified
- 401: 需要輸入賬號和密碼認證方能訪問資源;Unauthorized
- 403: 請求被禁止;Forbidden
- 404: 服務器無法找到客戶端請求的資源;Not Found
- 500: 服務器內部錯誤;Internal Server Error
- 502: 代理服務器從后端服務器收到了一條偽響應,如無法連接到網關;Bad Gateway
- 503: 服務不可用,臨時服務器維護或過載,服務器無法處理請求
- 504: 網關超時
5.HTTP 首部字段
HTTP 首部字段包含的信息最為豐富。首部字段同時存在於請求和響應報文內,並涵蓋 HTTP 報文相關的內容信息。使用首部字段是為了給客服端和服務器端提供報文主體大小、所使用的語言、認證信息等內容;
首部字段結構HTTP 首部字段是由首部字段名和字段值構成的,中間用冒號“:”分隔;
字段值對應單個 HTTP 首部字段可以有多個值;
報文首部中出現了兩個或以上具有相同首部字段名的首部字段時,在規范內尚未明確,根據瀏覽器內部處理邏輯的不同,優先處理的順序可能不同,結果可能並不一致。
通用首部:請求報文和響應報文兩方都會使用的首部
- Date:報文的創建時間
- Connection:連接狀態,如keep-alive, close
- Via:顯示報文經過的中間節點(代理,網關)
- Cache-Control:控制緩存,如緩存時長
- MIME-Version:發送端使用的MIME版本
- Warning:錯誤通知
請求首部:從客戶端向服務器端發送請求報文時使用的首部。補充了請求的附加內容、客戶端信息、請求內容相關優先級等信息
5.1請求首部:
- Accept:通知服務器自己可接受的媒體類型
- Accept-Charset: 客戶端可接受的字符集
- Accept-Encoding:客戶端可接受編碼格式,如gzip
- Accept-Language:客戶端可接受的語言
- Client-IP: 請求的客戶端IP
- Host: 請求的服務器名稱和端口號
- Referer:跳轉至當前URI的前一個URL
- User-Agent:客戶端代理,瀏覽器版本
5.2代理請求首部:
- Proxy-Authorization:向代理服務器認證
- 響應首部:從服務器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容信
- Age:從最初創建開始,響應持續時長
- Server:服務器程序軟件名稱和版本
- 協商首部:某資源有多種表示方法時使用
- Accept-Ranges:服務器可接受的請求范圍類型
- Vary:服務器查看的其它首部列表
- Set-Cookie:向客戶端設置cookie
- Set-Cookie2: 以上面相似
- WWW-Authenticate:來自服務器對客戶端的質詢列表
5.3實體首部:針對請求報文和響應報文的實體部分使用的首部。
補充了資源內容更新時間等與實體有關的的信息
- Location:告訴客戶端真正的實體位於何處
- Content-Encoding:對主體執行的編碼
- Content-Language:理解主體時最適合的語言
- Content-Length: 主體的長度
- Content-Location: 實體真正所處位置
- Content-Type:主體的對象類型,如text
緩存相關:
- ETag:實體的擴展標簽
- Expires:實體的過期時間
- Last-Modified:最后一次修改的時間
5.4擴展首部Cookie
HTTP 是一種無狀態協議。協議自身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個級別,協議對於發送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協議的可伸縮性,而特意把 HTTP 協議設計成如此簡單的。可是隨着 Web 的不斷發展,很多業務都需要對通信狀態進行保存。於是引入了 Cookie 技術。使用 Cookie 的狀態管理Cookie 技術通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息