記一次HTTP/TCP數據報的探究
實驗環境:
server:192.168.254.136,使用httpd作為web服務,復制nginx的首頁靜態頁作為demo
client:192.168.254.1,wireshark抓包
實驗步驟:
從客戶端訪問服務器端,抓取數據包。
報文摘錄:
報文分析:
1、第一步,老生成談的TCP三次握手機制,先進行了三次握手,然後建立連接,此處不再展開。
2、接下來,4號數據包是客戶端向服務器端發送HTTP的get請求,內容略。
3、然後是這次我要說的重點部分了。4號報文是客戶端向服務器端發送了請求,那麽5號報文則開始響應這次請求,第一個TCP包並沒有包含任何有效載荷,只有一個60字節的TCP頭。我們展開這個報文看看60字節包含什麽。
目的mac:6B
源mac: 6B
ipv4類型:2B
------------------------------------------------------------------------------------------------------------------------------
IP版本: 0.5B
頭部長度:0.5B
服務類型:1B
總長度: 2B
標識: 2B
標誌:3bits片偏移:13bits 共2B
TTL: 1B
協議: 1B
校驗和: 2B
源IP: 4B
目的
-------------------------------------------------------------------------------------------------------------------------------
源端口: 2B
目的端口:2B
序列號: 4B
確認號: 4B
頭部長度:0.5B
保留字段:6bits
URG/ACK/PSH/RST/SYN/FIN各1bit
窗口大小:2B
校驗和: 2B
緊急指針:2B
--------------------------------------------------------------------------------------------------------------------------------
padding:6B 填充字段,放置在數據鏈路層中。
IP報文分析:
4位版本號:IP協議(IPv4)版本號位4
4位頭部長度:標識頭部有多少個4字節,即最大共15*4個字節
8位服務類型:包含一個4位優先權字段:最小延時,最大吞吐量,最高可靠性和最小費用。
16位總長度:表示整個IP數據報的長度,最大表示65535,但由於MTU限制,一般無法到達這個值。
16位標識:唯一的標識數據報。系統采用加1的方式邊發送邊賦值。
3位標識(保留,DF禁止分片,MF更多分片):所以這個標誌是為分片存在,DF設置時禁止分片所以如果數據報太大則發送失敗。MF設置時,如果產生分片,除了最後一個分片,其他此片置1。
13位分片偏移:分片相對原始IP數據報開始處的偏移。
8位生存時間(TTL):數據報到達目的地之前允許經過的路由跳跳數。跳一下減1,得0丟棄。
8位協議:用來區分上層協議(ICMP為1,TCP為6,UDP為17)。
16位頭部校驗和:僅以CRC算法檢驗數據報頭部在傳輸過程中是否損壞。
32位源IP和目的IP。
TCP報文分析:
16位源端口號和16位目的端口號。
32位序號:一次TCP通信過程中某一個傳輸方向上的字節流的每個字節的編號,通過這個來確認發送的數據有序,比如現在序列號為1000,發送了1000,下一個序列號就是2000。
32位確認號:用來響應TCP報文段,給收到的TCP報文段的序號加1,三握時還要攜帶自己的序號。
4位頭部長度:標識該TCP頭部有多少個4字節,共表示最長15*4=60字節。同IP頭部。
6位保留。6位標誌。URG(緊急指針是否有效)ACK(表示確認號是否有效)PSH(提示接收端應用程序應該立即從TCP接收緩沖區讀走數據)RST(表示要求對方重新建立連接)SYN(表示請求建立一個連接)FIN(表示通知對方本端要關閉連接)
16位窗口大小:TCP流量控制的一個手段,用來告訴對端TCP緩沖區還能容納多少字節。
16位校驗和:由發送端填充,接收端對報文段執行CRC算法以檢驗TCP報文段在傳輸中是否損壞。
16位緊急指針:一個正的偏移量,它和序號段的值相加表示最後一個緊急數據的下一字節的序號。
分析完這60個字節的TCP報文之後再接著看6號報文,這個同樣是服務器端發送給客戶端的TCP報文,與上一個報文看看有何不同。我們來逐個對比一下上述字段。
首先就是整個IP數據報的長度不一樣了,一個是40一個是1500,然後標識不一樣了,由17800變成了17801,驗證了剛剛說的自增的方式排序。當然校驗和肯定也就不一樣了,所以IP數據報文只有這兩處不同,不算校驗和。
TCP報文中前面部分除了校驗和均相同,只是在最後附加了一個1460字節的數據字段,那麽多個數據包之間有什麽聯系呢?
我們單獨看5-8這幾個包,當客戶端發出請求後,服務器端先發送一個空的TCP包,所以Seq=1,Len=0,下一個包的Seq仍然是1,但是長度變成了1460,那麽第三個TCP包的Seq則為1+1460,即Seq2=Seq1+Len。而ACK不變,那麽客戶端接受之後發送反饋包,Seq為服務器端的Ack數字,Ack為上一個數據包的Seq+Len,即1461+1460=2921。
然後服務器端繼續向客戶端發送數據,9號報文的序列號為2921,是客戶端響應報文中的Ack,Ack仍然是370,長度為1460。10號報文的Seq也是9號報文的Seq+Len=2921+1460=4381,11號為客戶端響應報文,Seq保持370不變,Ack為4381+1460=5841。
同樣的道理,下面三個數據包也符合這個規律。最後傳輸完畢,第15個報文組成一段完整的HTTP報文。
但是需要註意的是,盡管第15個包在wireshark裏是寫的HTTP,但實際上這個包也是TCP的數據包,包含TCP的數據!
我們來看,前四行都是和普通的TCP報文是一樣的,並且長度為1431,不足1460,說明傳輸完成了。
最後兩行是HTTP報文,也就是說收到了全部的TCP傳輸報文,並合並為一個完整的HTTP應答報文。
然後TCP四次斷開,不再詳解。提示一點就是,16號包Seq是15號包中的Seq+Len 即:10192=8761+1431,17號包的Ack是16號包的Seq+1
記一次HTTP/TCP數據報的探究