作者:京東零售 王樂
一、從一個請求來看網絡分層原理
1.1 復雜的網絡
以下為一次請求過程中可能遇到的問題,預示著網絡的復雜性。
??
1.2 如何簡化復雜度
為了簡化網絡的復雜度,網絡通信的不同方面被分解為多層次結構,每一層只與緊挨著的上層或者下層進行交互,將網絡分層,這樣就可以修改,甚至替換某一層的軟件,只要層與層之間的接口保持不變,就不會影響到其他層。
1.2.1 OSI( Open System Interconnection Reference Model): 開放系統互聯參考模型
??
?
1.2.2 TCP/IP 協議族
??
1.2.3 兩種協議的對應關系
應用層:應用程序負責的部分
傳輸層:TCP、UDP、SCTP 等
網絡層:IPv4、IPv6等
數據鏈路層:以太網、無限LAN(WIFI)
物理層:光纖、雙絞線電纜、無線設備
??
1.3 一個請求的分層解析流程
請求各層之間都是調用對應層的接口(這個接口可以類比java中的接口,它可以有各種實現方式)。
1.在請求過程中域名是無法直接被計算機識別的,必須先轉換成ip,此時先檢測本地是否配置了host,如果沒有配置的話會發起一個dns請求。
2.DNS使用UDP作為傳輸層,DNS服務器IP配置在你的操作系統中,可以直接獲取。
3.數據鏈路層在接收到網絡層調用后,會通過IP使用ARP協議獲取當前IP對應的MAC地址。
4.最終通過物理層將數據傳入路由器,路由器進行逆向解析(MAC地址->IP),如果路由器判斷此信息不是給自己的會將信息繼續傳給下游電信運營商。
5.運營商判斷是DNS請求還是HTTP請求,如果是DNS請求會調用DNS服務器換取IP并返回。
6.獲取IP后DNS請求完成,此時再次發送一次HTTP請求,HTTP在傳輸層使用的是TCP協議,其他層同理。
7.運營商判斷如果非DNS請求,那么電信會通過運營商直接的協議進行消息的發送,最終找到ip對應的服務器。
8.接收端服務器的物理層接受到此次請求,通過對應的協議進行數據的層層解析獲取對應的信息,最終將數據傳給本地服務器(nginx、tomcat等),服務器將響應報文通過HTTP方式將數據返回。
一次請求的流轉如下圖:
??
二、HTTP協議
超文本傳輸協議(HyperText Transfer Protocol,HTTP): 一種無狀態的,以請求/應答方式運行的協議,它使用可擴展的語義和自描述消息格式,與 基于網絡的超文本信息系統靈活的互動
2.1 HTTP報文格式
請求報文和響應報文的結構基本相同。
起始行:描述請求或響應的基本信息。
頭部字段集合:key-value結構,報文的詳細信息。
消息體:真實傳輸的內容,可以是文本或二進制等。
2.1.1 HTTP請求報文
一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成,下圖給出了請求報文的一般格式。
??
2.1.1.1 請求行
請求行由請求方法字段、URL字段和HTTP協議版本字段3個字段組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
2.1.1.2 請求頭部
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知服務器有關于客戶端請求的信息,典型的請求頭有:
User-Agent:產生請求的瀏覽器類型。 Accept:客戶端可識別的內容類型列表。 Host:請求的主機名,允許多個域名同處一個IP地址,即虛擬主機。
2.1.1.3 空行
最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭。
2.1.1.4 請求數據
請求數據不在GET方法中使用,而是在POST方法中使用。POST方法適用于需要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭是Content-Type(這個主體的對象類型)和Content-Length(主體的長度)。
2.1.1.5 頭部字段注意事項
字段名不區分大小寫,字段名里不允許出現空格,可以使用連字符“-”,但不能使用下劃線“_”(有的服務器不會解析帶“_”的頭字段)。字段名后面必須緊接著“:”,不能有空格,而“:”后的字段值前可以有多個空格; 字段的順序是沒有意義的,可以任意排列不影響語義; 字段原則上不能重復,除非這個字段本身的語義允許,例如 Set-Cookie。
2.1.2 HTTP響應報文
HTTP響應也由三個部分組成,分別是:狀態行、消息報頭、響應正文。
??
2.1.2.1 狀態行格式如下
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服務器HTTP協議的版本;Status-Code表示服務器發回的響應狀態代碼;Reason-Phrase表示狀態代碼的文本描述。狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
?1xx:指示信息–表示請求已接收,繼續處理。
?2xx:成功–表示請求已被成功接收、理解、接受。
?3xx:重定向–要完成請求必須進行更進一步的操作。
?4xx:客戶端錯誤–請求有語法錯誤或請求無法實現。
?5xx:服務器端錯誤–服務器未能實現合法的請求。
常見狀態代碼、狀態描述的說明如下:
?200 OK:客戶端請求成功。
?400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。
?401 Unauthorized:請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用。
?403 Forbidden:服務器收到請求,但是拒絕提供服務。
?404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
?500 Internal Server Error:服務器發生不可預期的錯誤。
?503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間后可能恢復正常,舉個例子:HTTP/1.1 200 OK(CRLF)。
百度百科 狀態碼參考網址?
2.1.2.1 響應頭
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:Date,X-API-Request-Id
Content-Encoding:gzip
Content-Type:application/json;charset=UTF-8
Date:Sun, 10 Mar 2024 12:00:17 GMT
2.1.2.2 響應實體內容
服務器發給瀏覽器,要讓瀏覽器顯示的內容(html,js,css,圖片,數據等信息)。
三、HTTP請求完整過程
3.1 請求過程描述
1.首先瀏覽器先解析URL中的域名。
2.通過域名獲取對應的ip地址,上邊已經說過ip是通過DNS服務器獲取,我們可以在谷歌瀏覽器中查看到域名對應ip的解析。
3.獲取到IP地址后,瀏覽器就可以發起與服務器的三次握手
4.建立連接后,就開始組裝http請求,發送請求。
5.接收端收到請求后,開始處理請求解析請求頭中的數據,并生成對應的響應數據,給發送端返回響應數據。
6.瀏覽器收到響應后,會通過響應頭類型,解析對應的數據報文。
補充:上邊2中從瀏覽器中獲取域名的步驟。
瀏覽器中輸入:chrome://net-export/
打開對應文件搜索你想找的域名即可。
?
四、TCP協議
4.1 TCP協議描述
面向連接的,可靠的,基于字節流的傳輸層通信協議
4.2 TCP協議特點
?基于連接的:數據傳輸之前需要建立連接
?全雙工的:雙向傳輸
?客戶端和服務端可以互相雙向寫數據
?字節流:不限制數據大小,打包成報文段,保證有序接收,重復報文自動丟棄
?發送方:每次傳輸不限制數據大小,不是一次性將所有的數據都傳輸,會將數據切分成多個片段,并進行排序,通過網絡介質傳輸給接收方。
?接收方:不同的數據包會通過網絡不同的路線傳入接受方,因此接收方收到的數據有可能是亂序的,因此需要對數據包進行重排序。
?流量緩沖:解決雙方處理能力的不匹配
?可靠的傳輸服務:保證可達,丟包時通過重發機制實現可靠性
?擁塞控制:防止網絡出現惡性擁塞
?當網絡環境比較差的時候,會控制報文大小減小傳輸速率。
4.3 TCP連接管理
4.3.1 TCP連接四元組
四元組分別為:源地址、 源端口、 目的地址、 目的端口
4.3.2 TCP頭部格式
??
序列號:在建?連接時由計算機?成的隨機數作為其初始值,通過 SYN 包傳給接收端主機,每發送?次數據,就累加?次該數據字節數的??。?來解決?絡包亂序問題。
確認應答號:指下?次期望收到的數據的序列號,發送端收到這個確認應答以后可以認為在這個序號以前的數據都已經被正常接收。?來解決不丟包的問題。
控制位:
ACK:該位為 1 時,確認應答的字段變為有效,TCP 規定除了最初建?連接時的 SYN 包之外該位必須設置為 1 。
RST:該位為 1 時,表示 TCP 連接中出現異常必須強制斷開連接。
SYN:該位為 1 時,表示希望建?連接,并在其序列號的字段進?序列號初始值的設定。
FIN:該位為 1 時,表示今后不會再有數據發送,希望斷開連接。當通信結束希望斷開連接時,通信雙?的 主機之間就可以相互交換FIN位為 的 TCP 段。
URG:當URG=1時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應該盡快傳送,而不按照原來的排隊序列來傳送。
PSH:推送(PuSH),當兩個應用進程進行交互式的通信時,有時一端的應用進程希望在鍵入一個命令之后就能立即收到對方的響應。在這樣的情況下,就可以使用推送操作,此時,發送方將PSH置為1,并創建一個報文發送出去,接收端接受到該報文,發現PSH為1,就盡快交付接受應用進程,而不用等到整個緩存都滿了之后再向上交付。
緊急數據指針:當發送端需要發送一些緊急數據時,可以設置緊急指針來指示接收端,在接收到該指針之后盡快處理這些數據。緊急指針的值是一個相對于當前序列號的偏移量,用于指示緊急數據在整個數據流中的位置。
窗口大小:當前服務器緩存可接受的數據報文大小。
4.4 TCP 三次握手
??
說明:
1.開始時服務端和客戶端的連接處于斷開狀態。
2.服務端啟動后會監聽特定端口,處于監聽狀態,等待客戶端的請求。
3.客戶端發起請求,變更成發送狀態,此時會在請求中攜帶同步序列號 x。
4.服務端接受到請求后,保存客戶端對應的信息,并發送確認收到應答消息,此消息的應答碼需要在x的基礎上加1,此時服務端處于等待客戶端確認狀態。
5.客戶端收到服務端確認后,狀態變更為已連接,客戶端也需要給服務端回復確認收到,此時應答碼為服務端確認碼y+1。
6.服務端收到客戶端確認消息后,狀態變更為已連接。
7.連接建立成功,此為三次握手。
8.握手過程中會消耗序號,建立鏈接后不會消耗。
以下是三次握手的示例過程:
??
4.5 TCP 四次揮手
??
說明:
1.客戶端和服務端都可以主動發起關閉連接。
2.圖中為客戶端發起關閉連接,首先客戶端發起 FIN 關閉連接請求。
3.服務端收到關閉請求后,先回復收到關閉請求的確認消息給客戶端,此時客戶端處于等待關閉2狀態,等待服務端完成收尾工作,服務端完成收尾(剩余未完成傳輸數據同步),執行關閉連接方法,并給客戶端發送FIN 關閉鏈接請求。
4.客戶端收到關閉請求后,給服務端回復確認關閉應答消息,服務端關閉,客戶端處于等待狀態,此時需要等待兩個最大請求時長(防止服務端由于網絡原因未收到應答消息,服務端會重試發送FIN消息)。
5.等待時間到期后關閉連接。
4.5 TCP 可靠性傳輸
4.5.1 停止等待協議
描述:沒傳送一個報文,服務端都回復一個確認消息,效率低下。
??
4.5.1 重傳機制
4.5.1.1 ack丟失
描述:如果出現丟包如何處理
??
4.5.1.2 報文丟失
??
4.5.2 滑動窗口協議與累計確認(延時ack)
??
說明:
1.約定窗口大小為4,每次發送四個報文。
2.服務端收到后只收到,1,2,4。 3丟失,此時服務端確認只確認到2。
3.客戶端收到確認后,從3開始在滑動下一個窗口,進行數據傳輸。
參考文獻
OSI參考模型: https://baike.baidu.com/item/OSI%E5%8F%82%E8%80%83%E6%A8%A1%E5%9E%8B/708028?fr=aladdin
HTTP狀態碼: https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81?fromModule=lemma_search-box
TCP協議: https://baike.baidu.com/item/TCP/33012?fr=ge_ala
TCP與UDP的可靠性傳輸: https://zhuanlan.zhihu.com/p/636141175
審核編輯 黃宇
-
計算機
+關注
關注
19文章
7626瀏覽量
90154 -
網絡協議
+關注
關注
3文章
273瀏覽量
21990
發布評論請先 登錄
評論