TCP三次握手&Render Tree頁面渲染=>從輸入URL到頁面顯示的過程?
最近工作之余一直在溫故js系列,想知新,想提升,以小技術(shù)點為節(jié)奏去回顧。今天突然想到回顧一下這個http知識,http知識有太多深層次需要學(xué)習(xí),今天簡要回顧,淺析下這個技術(shù)點。
主要通過五個步驟淺析這個過程,有錯誤的地方,煩請斧正,互相學(xué)習(xí)。
艾瑪,我只是淺析一下,深析請見:http://fex.baidu.com/blog/201...
這個知識太復(fù)雜了,以前看的時候頭暈O(∩_∩)O~
1、發(fā)送URL,請求IP地址
當(dāng)發(fā)送一個URL請求時,不管這個URL是Web頁面的URL還是Web頁面上每個資源的URL,瀏覽器都會開啟一個線程來處理這個請求,同時在遠程DNS服務(wù)器上啟動一個DNS查詢,讓瀏覽器獲得請求對應(yīng)的IP地址。(這兒涉及的“DNS 查詢和通過 Socket 發(fā)送數(shù)據(jù)”知識點見鏈接文章)
2、TCP三次握手
瀏覽器與遠程 Web 服務(wù)器通過 TCP 三次握手協(xié)商來建立一個 TCP/IP 連接。該握手包括一個同步報文,一個同步-應(yīng)答報文和一個應(yīng)答報文,這三個報文在 瀏覽器和服務(wù)器之間傳遞。該握手首先由客戶端嘗試建立起通信,而后服務(wù)器應(yīng)答并接受客戶端的請求,最后由客戶端發(fā)出該請求已經(jīng)被接受的報文。
ACK: ACK=1表示該報文段中有確認號需要處理。
SYN: SYN=1 ACK=0表明是建立連接請求報文段,SYN=1 ACK=1表明同意建立連接報文。
FIN: FIN=1表示對端的數(shù)據(jù)已經(jīng)發(fā)送完畢,要求釋放連接。
第一次握手:建立連接
客戶端發(fā)送連接請求報文段,將SYN值設(shè)為1,Sequence Number為x。客戶端進入SYN_SEND狀態(tài),等待服務(wù)器的確認。
第二次握手:服務(wù)器收到SYN報文段
服務(wù)器收到客戶端SYN報文段,需要對這個SYN報文段進行確認,設(shè)置Acknowledgment Number為x+1(Sequence Number+1)。同時,自己自己還要發(fā)送SYN請求信息,將SYN值設(shè)為1,Sequence Number設(shè)為y。服務(wù)器端將上述所有信息放到一個報文段(即SYN+ACK報文段)中,一并發(fā)送給客戶端,服務(wù)器進入SYN_RECV狀態(tài)。
第三次握手:客戶端收到SYN+ACK報文段
客戶端收到服務(wù)器的SYN+ACK報文段后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報文段,這個報文段發(fā)送完畢以后,客戶端和服務(wù)器端都進入ESTABLISHED狀態(tài),完成TCP三次握手。
完成三次握手,客戶端與服務(wù)器開始傳送數(shù)據(jù),在上述過程中,還有一些重要的概念:
未連接隊列:在三次握手協(xié)議中,服務(wù)器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設(shè)一個條目,該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認,正在等待客戶的確認包。這些條目所標(biāo)識的連接在服務(wù)器處于Syn_RECV狀態(tài),當(dāng)服務(wù)器收到客戶的確認包時,刪除該條目,服務(wù)器進入ESTABLISHED狀態(tài)。 Backlog參數(shù):表示未連接隊列的最大容納數(shù)目。
SYN-ACK 重傳次數(shù):服務(wù)器發(fā)送完SYN-ACK包,如果未收到客戶確認包,服務(wù)器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數(shù)超過系統(tǒng)規(guī)定的最大重傳次數(shù),系統(tǒng)將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務(wù)從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間為Timeout時間、SYN_RECV存活時間。
為什么是3次握手?
圖片及問題轉(zhuǎn)自jimmy_thr的https://segmentfault.com/a/11...
很簡單呀,因為3次就夠了,干嘛用4次。23333. 舉個例子吧,假如是2次的話, 可能會出現(xiàn)這樣一個情況。
當(dāng)客戶端發(fā)送一次請求A后,但是A在網(wǎng)絡(luò)延遲了很久, 接著客戶端又發(fā)送了一次B,但是此時A已經(jīng)無效了。 接著服務(wù)器相應(yīng)了B,并返回TCP連接頭,建立連接(這里就2次哈)。 然后,A 歷經(jīng)千山萬水終于到服務(wù)器了, 服務(wù)器一看有請求來了,則接受,由于一開始A帶著的TCP格式都是正確的,那么服務(wù)器,理所應(yīng)當(dāng)?shù)囊卜祷爻晒B接的flag,但是,此時客戶端已經(jīng)判斷該次請求無效,廢棄了。 然后服務(wù)器,就這么一直掛著(浪費資源),造成的一個問題是,md, 這個鍋是誰的? 所以,為了保險起見,再補充一次連接就可以了。所以3次是最合適的。在Chinese中,以3為起稱為多,如果你用4,5,6,7,8...次的話,這不更浪費嗎?
3、服務(wù)器響應(yīng)200
TCP/IP 連接建立后,瀏覽器會通過該連接向遠程服務(wù)器發(fā)送 HTTP 的 GET 請求。遠程服務(wù)器找到資源并使用 HTTP 響應(yīng)返回該資源,值為200的 HTTP 響應(yīng)狀態(tài)表示一個正確的響應(yīng)。
4、生成Render Tree
客戶端開始下載資源。請求返回后,便進入了我們關(guān)注的前端模塊。瀏覽器會解析 HTML 成樹形的數(shù)據(jù)結(jié)構(gòu)DOM,生成 DOM Tree,瀏覽器將CSS代碼解析成樹形的數(shù)據(jù)結(jié)構(gòu)CSSOM,生成 CSS Rule Tree。
DOM 和 CSSOM 都是以 Bytes → characters → tokens → nodes → object model 這樣的方式生成最終的數(shù)據(jù)。DOM樹的構(gòu)建過程是一個深度遍歷過程:當(dāng)前節(jié)點的所有子節(jié)點都構(gòu)建好后才會去構(gòu)建當(dāng)前節(jié)點的下一個兄弟節(jié)點。
DOM Tree和CSS Rule Tree結(jié)合生成Render Tree。
display:none 的節(jié)點不會被加入Render Tree,而visibility: hidden 則會。
• display : 隱藏對應(yīng)的元素但不擠占該元素原來的空間。
• visibility: 隱藏對應(yīng)的元素并且擠占該元素原來的空間
所以,如果某個節(jié)點最開始是不顯示的,設(shè)為display:none是更優(yōu)的。
5、渲染頁面
布局
有了Render Tree,瀏覽器知道網(wǎng)頁中有哪些節(jié)點、各個節(jié)點的CSS定義以及他們的從屬關(guān)系。接著就開始布局,計算出每個節(jié)點在屏幕中的位置。
渲染
瀏覽器已經(jīng)知道了哪些節(jié)點要顯示、每個節(jié)點的CSS屬性是什么、每個節(jié)點在屏幕中的位置是哪里。就進入了最后一步,按照算出來的規(guī)則,通過顯卡,把內(nèi)容畫到屏幕上。
而 javascript 又可以根據(jù) DOM API 操作DOM。比如JS修改了DOM或者CSS屬性,也會重新觸發(fā)布局和渲染的執(zhí)行過程。
關(guān)于這個問題到這兒就可以結(jié)束了......圖已放,情未了,那順便把TCP四次揮手也寫這,結(jié)合圖去分析。
遺留:TCP四次揮手
第一次揮手:客戶端想分手
假設(shè)客戶端想要關(guān)閉連接,客戶端發(fā)送一個 FIN 標(biāo)志位置為1的包(FIN=1,seq=x),表示自己已經(jīng)沒有數(shù)據(jù)可以發(fā)送了,但是仍然可以接受數(shù)據(jù)。
發(fā)送完畢后,客戶端進入 FIN_WAIT_1 狀態(tài)。
第二次揮手:服務(wù)端也想分手
服務(wù)器端確認客戶端的 FIN包,發(fā)送一個確認包(ACK=1,ACKnum=x+1),表明自己接受到了客戶端關(guān)閉連接的請求,但還沒有準(zhǔn)備好關(guān)閉連接。
發(fā)送完畢后,服務(wù)器端進入 CLOSE_WAIT 狀態(tài),客戶端接收到這個確認包之后,進入FIN_WAIT_2 狀態(tài),等待服務(wù)器端關(guān)閉連接。
第三次揮手:服務(wù)端準(zhǔn)備好分手
服務(wù)器端準(zhǔn)備好關(guān)閉連接時,向客戶端發(fā)送結(jié)束連接請求,F(xiàn)IN置為1(FIN=1,seq=y)。
發(fā)送完畢后,服務(wù)器端進入 LAST_ACK 狀態(tài),等待來自客戶端的最后一個ACK。
第四次揮手:分手
客戶端接收到來自服務(wù)器端的關(guān)閉請求,發(fā)送一個確認包(ACK=1,ACKnum=y+1),并進入 TIME_WAIT狀態(tài),等待可能出現(xiàn)的要求重傳的 ACK包。
服務(wù)器端接收到這個確認包之后,關(guān)閉連接,進入 CLOSED 狀態(tài)。
客戶端等待2MSL(2MSL,2 Maximum Segment Lifetime)之后,沒有收到回復(fù),確保服務(wù)器端確實是關(guān)閉了,客戶端也關(guān)閉連接,進入 CLOSED狀態(tài)。
學(xué)知識不會是為了面試,因為面試會一層層的深入,不知道的就是不知道,不能逞強,最后坑了自己。多研究研究,才是真理。come on , basketball.
學(xué)習(xí)參考:http://delai.me/code/js-and-p...
學(xué)習(xí)參考:https://segmentfault.com/a/11...