偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

最經(jīng)典的前端面試題之一,你能答出什么幺蛾子?

開(kāi)發(fā) 前端
本文的目標(biāo)是以“輸入 URL 后發(fā)生了什么”這個(gè)經(jīng)典面試題為引子,寫(xiě)一篇既能夠涵蓋面試中大部分網(wǎng)絡(luò)試題,又能夠?qū)ⅰ拜斎?URL 后發(fā)生什么”講得有深度的文章。

本文的目標(biāo)是以“輸入 URL 后發(fā)生了什么”這個(gè)經(jīng)典面試題為引子,寫(xiě)一篇既能夠涵蓋面試中大部分網(wǎng)絡(luò)試題,又能夠?qū)?ldquo;輸入 URL 后發(fā)生什么”講得有深度的文章。以前寫(xiě)過(guò)一篇類似的文章,但實(shí)在過(guò)于簡(jiǎn)單。另外,HTTPS 逐漸普及,文章中沒(méi)有這部分過(guò)程也說(shuō)不過(guò)去。不想修改原來(lái)的文章,就重新寫(xiě)一篇吧。文中以我所在的項(xiàng)目“興趣部落”的官網(wǎng) https://buluo.qq.com/index.html 為例子。

生成 HTTP 請(qǐng)求消息

解析完要訪問(wèn)的目標(biāo)服務(wù)器是啥了,接下來(lái)瀏覽器就會(huì)用 HTTP 協(xié)議生成請(qǐng)求消息去 web服務(wù)器請(qǐng)求資源,消息格式如下:

 

請(qǐng)求信息主要包括:

  • 請(qǐng)求行:請(qǐng)求的方法(POST/GET/…)、URL、HTTP版本(1.1/2);
  • 消息頭:請(qǐng)求的附加信息,以空行結(jié)束;
  • 消息體:數(shù)據(jù),比如 POST 請(qǐng)求時(shí)的表單數(shù)據(jù)。

對(duì)應(yīng)的,響應(yīng)消息也有 3 個(gè)部分組成:

  • 狀態(tài)行:HTTP版本、狀態(tài)碼(200/304/404/…)、解釋狀態(tài)的響應(yīng)短語(yǔ);
  • 消息頭
  • 消息體:返回的數(shù)據(jù)。

用圖表示:

 

DNS

生成 HTTP 消息后,瀏覽器委托操作系統(tǒng)將消息發(fā)送給 web服務(wù)器。而通過(guò) web服務(wù)器的名稱是沒(méi)法找到服務(wù)器在哪的,好比知道一個(gè)人的名字沒(méi)法找到他家在哪一樣,網(wǎng)絡(luò)中的地址是用 IP 地址表示的,所以要想跟服務(wù)器通信,得先找到它的 IP 地址,使用 DNS(Domain Name System,域名服務(wù)系統(tǒng)) 服務(wù)器可以將 web服務(wù)器名稱轉(zhuǎn)換成 IP 地址。那這個(gè)過(guò)程是怎樣的呢?

操作系統(tǒng)有一個(gè) Socket 庫(kù),這個(gè)庫(kù)中的程序主要是讓?xiě)?yīng)用程序調(diào)用操作系統(tǒng)的網(wǎng)絡(luò)功能,而在這些功能中,瀏覽器需要調(diào)取操作系統(tǒng)的 DNS 解析功能。DNS 解析器生成一條表示“告訴我 https://buluo.qq.com/index.html 的 IP 地址”的消息,然后委托操作系統(tǒng)的協(xié)議棧發(fā)送 UDP 消息到 DNS 服務(wù)器。那這條消息是如何發(fā)送到 DNS 服務(wù)器又是如何將 IP 地址返回的呢?

首先介紹下操作系統(tǒng)中 DNS 解析器發(fā)送給 DNS 服務(wù)器的消息內(nèi)容,消息中包含 1)域名:buluo.qq.com;2)Class: IN,代表當(dāng)前的網(wǎng)絡(luò)是因特網(wǎng),DNS 設(shè)計(jì)之初還考慮了其他網(wǎng)絡(luò),雖然現(xiàn)在只有互聯(lián)網(wǎng),但這個(gè)字段還是保留了下來(lái);3)記錄類型:A,表示域名對(duì)應(yīng)的是 IP 地址,因?yàn)?DNS 還能解析其他地址,比如類型為 MX 時(shí) DNS 服務(wù)器會(huì)查詢郵件服務(wù)器地址。DNS 服務(wù)器中維護(hù)一張表,表的每一項(xiàng)包含上面三個(gè)字段還有服務(wù)器地址,當(dāng)域名、Class、記錄類型全部匹配時(shí),DNS 服務(wù)器返回地址,在例子中會(huì)返回興趣部落首頁(yè)的 IP 地址。

但這個(gè)時(shí)候問(wèn)題來(lái)了,世界上有不計(jì)其數(shù)的服務(wù)器,將這些所有的服務(wù)器信息都保存在一個(gè) DNS 的表中肯定是不現(xiàn)實(shí)的,所以肯定有很多臺(tái) DNS 服務(wù)器一起配合完成這個(gè)域名解析過(guò)程的,那具體過(guò)程是什么樣的呢?

首先,DNS 服務(wù)器中的所有信息都是按照域名來(lái)劃分層次的,這個(gè)層次是用 . 來(lái)分隔的,越靠右層次越高,比如 “buluo.qq.com” 中 “com” 層次最高,“qq” 次之,“buluo” 最后,其中每一層都被稱為“域”,比如 “com 域”下是 “qq” 域,再下是 “buluo” 域,域的層次劃分是為了更好地分配給不同國(guó)家、公司和組織等,典型的例子像南京市政府的官網(wǎng):“www.nanjing.gov.cn”,“cn” 代表中國(guó)這個(gè)國(guó)家的域,“gov” 代表這個(gè)國(guó)家下的政府組織,“nanjing” 代表南京市政府。域有層次之分,那 DNS 服務(wù)器呢?規(guī)定將管理下級(jí)域的 DNS 服務(wù)器的 IP地址注冊(cè)到上級(jí)的 DNS 服務(wù)器中,比如管理 “buluo.qq.com” 這個(gè)域的 DNS 服務(wù)器的 IP地址需要注冊(cè)到 “qq.com” 域的 DNS 服務(wù)器中,以此類推,一直到“根域”,就是 “cn”、“com” 這類域的上一層次,根域中就保存了 “cn”、“com” 等域名的 DNS 服務(wù)器信息。此外,還需要將根域的 DNS 服務(wù)器信息保存在所有的 DNS 服務(wù)器中,這樣只要找到一臺(tái) DNS 服務(wù)器就可以順藤摸瓜找到下層任何一個(gè) DNS 服務(wù)器。知道了域的層次劃分以及 DNS 服務(wù)器的分布,下面就正式介紹如何尋找到相應(yīng)的 DNS 服務(wù)器并獲取 IP 地址。

首先,客戶端會(huì)訪問(wèn)最近的一臺(tái) DNS 服務(wù)器,但由于這臺(tái) DNS 服務(wù)器上沒(méi)有 “buluo.qq.com” 這個(gè)域名的對(duì)應(yīng)的信息,所以就向根域 DNS 服務(wù)器發(fā)請(qǐng)求詢問(wèn),但根域中也沒(méi)有,但判定這個(gè)域名是屬于 “com” 域的,所以就返回其管理的 “com” 域的 DNS 服務(wù)器的 IP 地址,意思是“雖然我不知道,但你可以去某某處問(wèn)問(wèn),他應(yīng)該知道”。然后 最近的那個(gè) DNS 服務(wù)器又向 “com” 域的 DNS 服務(wù)器發(fā)請(qǐng)求,同理,也不知道,然后返回 “qq.com” 域的 DNS 服務(wù)器,然后這臺(tái)最近的 DNS 服務(wù)器又向 “qq.com” 域 DNS 服務(wù)器發(fā)請(qǐng)求,仍然沒(méi)有,直到最后,向 “buluo.qq.com” 這個(gè)域下的 DNS 服務(wù)器發(fā)請(qǐng)求才拿到 IP 地址。接著,這臺(tái)最近的 DNS 服務(wù)器將獲得的 “buluo.qq.com” 的 IP 地址返回給客戶端,客戶端再拿著這個(gè) IP 地址去請(qǐng)求資源。以上的過(guò)程用圖表示如下:

 

以上就是通過(guò) DNS 服務(wù)獲取目標(biāo)服務(wù)器 IP 地址的過(guò)程,可以說(shuō)是非常耗時(shí),為了優(yōu)化性能,DNS 服務(wù)器會(huì)對(duì)中間的查詢結(jié)果做個(gè)緩存,為了保存緩存的實(shí)時(shí)性,每隔一段時(shí)間就會(huì)將緩存設(shè)為過(guò)期。

委托協(xié)議棧發(fā)送消息

現(xiàn)在客戶端拿到了目標(biāo)服務(wù)器的 IP 地址,下面就要與其連接并發(fā)送消息了,這個(gè)過(guò)程同樣不是瀏覽器做的,而是委托協(xié)議棧來(lái)完成的,具體過(guò)程是:

  1. 操作系統(tǒng)創(chuàng)建一個(gè)套接字,協(xié)議棧返回一個(gè)描述符,瀏覽器存儲(chǔ)起來(lái),這個(gè)描述符是套接字的 ID,用于識(shí)別套接字,原因是同一個(gè)客戶端可能跟很多服務(wù)器同時(shí)連接;
  2. 客戶端的套接字與服務(wù)端的套接字進(jìn)行連接,連接成功后,協(xié)議棧將目標(biāo)服務(wù)器的 IP 地址和端口號(hào)保存在套接字中,下面就可以收發(fā)數(shù)據(jù);
  3. 發(fā)送的數(shù)據(jù)是 HTTP 請(qǐng)求消息,發(fā)送的過(guò)程是:瀏覽器通過(guò)描述符查找到指定的套接字,并向套接字發(fā)送數(shù)據(jù),數(shù)據(jù)便會(huì)通過(guò)網(wǎng)絡(luò)傳輸?shù)椒?wù)端的套接字,服務(wù)器接收到消息后處理然后返回響應(yīng)消息;
  4. 消息返回后會(huì)被放入一塊內(nèi)存緩沖區(qū)內(nèi),瀏覽器可以直接讀取這段消息。之后,操作系統(tǒng)斷開(kāi)套接字連接,本地的套接字也會(huì)被刪除。

TCP 連接

在“委托協(xié)議棧發(fā)送消息”部分簡(jiǎn)單地提了下客戶端和服務(wù)端利用套接字進(jìn)行連接,那這個(gè)連接具體是什么樣的呢?

首先什么是套接字?套接字其實(shí)就是個(gè)放在內(nèi)存的備忘錄,協(xié)議棧在發(fā)送數(shù)據(jù)時(shí)先看一眼備忘錄,了解這個(gè)數(shù)據(jù)是發(fā)到哪個(gè)端口,當(dāng)數(shù)據(jù)發(fā)送出去后,這個(gè)備忘錄還得記錄什么時(shí)間收到響應(yīng)、什么時(shí)候斷開(kāi)等控制信息,協(xié)議棧需要根據(jù)這些信息來(lái)決定下一步做什么。

客戶端和服務(wù)端的連接是通過(guò)套接字連接的,那“連接”又是什么意思呢?連接實(shí)際上是客戶端和服務(wù)端互相交換控制信息的過(guò)程,控制信息主要包含兩種,一種是上面提到的套接字里要來(lái)幫助協(xié)議棧進(jìn)行下一步操作的信息,另一種是客戶端和服務(wù)端通信時(shí)交換的控制信息,這種控制信息就是我們俗稱的 TCP 頭部。 那連接的過(guò)程是怎樣的呢?

這個(gè)連接過(guò)程就是我們平時(shí)經(jīng)常聽(tīng)到的三次握手。

  • 首先客戶端創(chuàng)建 TCP 頭部,頭部包含目標(biāo)服務(wù)器的端口號(hào)等,同時(shí)將頭部的 SYN 設(shè)為 1,表示開(kāi)始請(qǐng)求連接。TCP 頭部創(chuàng)建好了之后,TCP 模塊便將信息傳遞給 IP 模塊并委托它發(fā)送,然后信息經(jīng)過(guò)網(wǎng)絡(luò)到達(dá)服務(wù)器的 IP 模塊再到 TCP 模塊,TCP 模塊則會(huì)根據(jù) TCP 頭部的信息找到端口號(hào)對(duì)應(yīng)的套接字,套接字則會(huì)寫(xiě)入相應(yīng)的信息,然后將狀態(tài)改為“正在連接”;
  • 服務(wù)端的 TCP 模塊收到連接請(qǐng)求后就要回應(yīng),與客戶端一樣, 需要在 TCP 頭部設(shè)置發(fā)送方和接收方的端口號(hào),以及將 SYN 設(shè)為 1,同時(shí),返回響應(yīng)時(shí)還要將 ACK 設(shè)為 1,表示已經(jīng)接收到相應(yīng)的包。接著,將信息打包好,發(fā)送給客戶端;
  • 客戶端收到消息后,發(fā)現(xiàn) SYN 為 1,則表示連接成功,所以在套接字中寫(xiě)入服務(wù)器的端口號(hào),同時(shí)將狀態(tài)改為連接完畢。為了告訴服務(wù)器收到消息,客戶端也要將 ACK 設(shè)為 1,接著發(fā)送給服務(wù)端。

整個(gè)過(guò)程用圖表示如下:

 

HTTPS 的握手過(guò)程

上面的過(guò)程是最簡(jiǎn)單的 HTTP 三次握手,但現(xiàn)在越來(lái)越多的網(wǎng)站使用了 HTTPS 協(xié)議,那與 HTTP 連接有什么不同呢?

先介紹一下什么是 HTTPS。HTTPS 正如其名字,HTTP 代表其并不是自己創(chuàng)建一個(gè)新的協(xié)議,而是建立在 HTTP 的基礎(chǔ)之上,S 代表其是安全的,如何保證安全?利用 SSL/TLS。SSL(Secure Sockets Layer,安全套接層)是網(wǎng)景設(shè)計(jì)的安全傳輸協(xié)議,經(jīng)歷了 1.0、2.0 和 3.0 版本,但因?yàn)?1.0 有嚴(yán)重安全缺陷,所以從未公布。后來(lái) IETF 將 SSL 標(biāo)準(zhǔn)化,稱為 TLS(Transport Layer Security, 傳輸層安全協(xié)議) ,TLS 1.0 與 SSL 3.0 差別很小。TLS 經(jīng)歷了 1.0、1.1 到現(xiàn)在最新的 1.2。在 HTTPS 通信中具體使用哪一種還要看客戶端和服務(wù)端的支持程度。那 SSL/TLS 在網(wǎng)絡(luò)模型中屬于哪一層呢?直接上圖:

 

在客戶端和服務(wù)端通過(guò) HTTPS 連接的過(guò)程中,除了正常的 HTTP 連接中的事情,還有身份驗(yàn)證和加密信息兩件事,下面看看具體過(guò)程(更詳細(xì)內(nèi)容可以查看標(biāo)準(zhǔn):RFC5246)。

  • Client Hello:這次握手是客戶端向服務(wù)端發(fā)起加密通信請(qǐng)求,請(qǐng)求中包含以下關(guān)鍵信息:
    • Version:客戶端支持的協(xié)議版本,比如 TLS 1.2;
    • Random:第一個(gè)隨機(jī)數(shù),作用在后面的握手步驟中介紹;
    • Session ID:“空”表示這是一次新的連接,“不為空”表示維持前面的連接;
    • Cipher Suites:密碼套件;
    • Compression:客戶端支持的壓縮方法;
    • Extensions:擴(kuò)展。
  • Server Hello:服務(wù)端收到客戶端消息后返回響應(yīng),響應(yīng)信息跟 ClientHello 類似,只不過(guò)每個(gè)字段都是一個(gè)確定的值,是服務(wù)端根據(jù)客戶端傳過(guò)來(lái)的候選值的最終選擇結(jié)果,如果服務(wù)端沒(méi)有在候選值中找到合適的,那么將會(huì)返回錯(cuò)誤提示,需要提一下的是,這次的響應(yīng)信息中包含第二個(gè)隨機(jī)數(shù)。
  • Server Certificate:服務(wù)端緊接著向客戶端發(fā)送證書(shū);
  • Server Key Exchange Message:當(dāng)上一條證書(shū)消息中的信息不全時(shí),服務(wù)端會(huì)再次發(fā)送一些額外數(shù)據(jù)到客戶端;
  • Certificate Request:如果服務(wù)端要求客戶端提供證書(shū),會(huì)發(fā)出這樣一個(gè)請(qǐng)求;
  • Server Hello Done:這條消息表示服務(wù)端這階段數(shù)據(jù)發(fā)送完畢,下面就是等待客戶端的響應(yīng);
  • Client Certificate:如果服務(wù)端要求客戶端提供證書(shū),那么客戶端會(huì)返回自己的證書(shū);
  • Client Key Exchange Message:這一步非常關(guān)鍵,客戶端會(huì)生成 premaster secret(預(yù)主密鑰),為什么叫 premaster secret?因?yàn)楹竺婵蛻舳撕头?wù)端會(huì)根據(jù) premaster secret 和前面過(guò)程中兩個(gè)隨機(jī)數(shù)共同生成一個(gè) master secret(主密鑰,48字節(jié)),后面通信的安全全靠這個(gè) master secret。前兩個(gè)隨機(jī)數(shù)客戶端和服務(wù)端都知道了,這個(gè)步驟最主要的就是協(xié)商一個(gè) premaster secret,這個(gè)過(guò)程叫做“密鑰交換”,這里介紹兩個(gè)方法:
    • RSA 密鑰交換:客戶端生成 46 字節(jié)的隨機(jī)數(shù),使用服務(wù)器的公鑰加密,然后發(fā)送出去,服務(wù)器便可以用私鑰解密。但這種方式不太安全,所以現(xiàn)在逐漸使用 DH 密鑰交換;
    • Diffie-Hellman 密鑰交換:DH 的精髓就是正向計(jì)算簡(jiǎn)單,反向計(jì)算困難,好比兩種顏色的顏料,混在一起你知道什么顏色,但就給你一種顏色,你幾乎沒(méi)法說(shuō)出其是由哪兩種顏色混合而來(lái)。具體生成 premaster secret 的方式可以看Diffie–Hellman key exchange,這里簡(jiǎn)單提一下,密鑰交換需要 6 個(gè)參數(shù),其中 2 個(gè)叫“域參數(shù)”,由服務(wù)器選取,交換過(guò)程中客戶端和服務(wù)器各自生成 2 個(gè)參數(shù),但是只相互發(fā)送 1 個(gè),所以客戶端和服務(wù)器各自知道 5 個(gè)參數(shù),根據(jù)這 5 個(gè)參數(shù),雙方計(jì)算得到一個(gè)同樣的 premaster secret。
  • Certificate Verify:驗(yàn)證客戶端的私鑰和之前發(fā)送的客戶端證書(shū)中的公鑰是對(duì)應(yīng)的;
  • Finished:客戶端的握手已經(jīng)完成,消息內(nèi)容加密,并且包含 verify_data 字段,值是整個(gè)握手過(guò)程中所有消息的摘要,供服務(wù)端驗(yàn)證消息完整性;
  • Finished:表示服務(wù)端握手結(jié)束,同時(shí)也發(fā)送前面過(guò)程的消息的摘要。

用圖表示一下就是:

 

整個(gè)握手過(guò)程總結(jié)一下就是:

  • 客戶端提出 HTTPS 連接請(qǐng)求;
  • 服務(wù)器表明身份,表示自己是李逵而不是李鬼;
  • 客戶端生成一個(gè)用于以后通信的密鑰,并把密鑰也告訴了服務(wù)器;
  • 客戶端和服務(wù)器結(jié)束握手。

以上就是握手的整個(gè)通信細(xì)節(jié),但細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn)少了一個(gè)重要步驟,客戶端收到服務(wù)器發(fā)來(lái)的證書(shū)時(shí)是如何判定對(duì)方就是自己想要找的服務(wù)器呢?這時(shí)候就要驗(yàn)證證書(shū)的有效性,證書(shū)就像現(xiàn)實(shí)中的身份證,可以確認(rèn)某個(gè)網(wǎng)站的確是我要訪問(wèn)的網(wǎng)站。那怎么驗(yàn)證證書(shū)的有效性呢?首先,數(shù)字證書(shū)和身份證一樣由權(quán)威機(jī)構(gòu)簽發(fā),不同的是身份證只能由政府簽發(fā),而數(shù)字證書(shū)由 CA(Certification Authorities,數(shù)字證書(shū)認(rèn)證機(jī)構(gòu))簽發(fā),Mac 用戶可以通過(guò)“文件-應(yīng)用程序-實(shí)用工具-鑰匙串訪問(wèn)”來(lái)查看根 CA,根 CA 可以簽發(fā)其他 CA,所以一個(gè)網(wǎng)站的簽發(fā)者不是根 CA 也沒(méi)關(guān)系,只要這個(gè) CA 的簽發(fā)者是根 CA 也行。了解了 CA,下面看一下證書(shū)包含什么,先看圖:

 

證書(shū)中包含:網(wǎng)站的基本信息、網(wǎng)站的公鑰、CA 的名字等信息(詳細(xì)請(qǐng)看 X.509),然后 CA 根據(jù)這幾個(gè)內(nèi)容生成摘要(digest),再對(duì)摘要用 CA 的私鑰加密,加密后的結(jié)果即數(shù)字簽名,最后將數(shù)字簽名也放入到證書(shū)中。那么當(dāng)系統(tǒng)收到一個(gè)證書(shū)后,先用公鑰解密,解得開(kāi)說(shuō)明對(duì)方是由權(quán)威 CA 簽發(fā)的,然后再根據(jù)證書(shū)的信息生成摘要,跟解密出來(lái)的摘要對(duì)比。

數(shù)據(jù)傳輸

建立連接之后,客戶端和服務(wù)端便可以開(kāi)始進(jìn)行數(shù)據(jù)傳輸。同樣,瀏覽器委托協(xié)議棧來(lái)幫忙收發(fā)消息,協(xié)議棧收到消息后不會(huì)立即發(fā)送出去,而是先放入到緩存區(qū)中,因?yàn)橄騾f(xié)議棧發(fā)送的數(shù)據(jù)長(zhǎng)度由瀏覽器控制,如果協(xié)議棧一收到數(shù)據(jù)就發(fā)送出去,那么可能會(huì)發(fā)送大量小包,導(dǎo)致網(wǎng)絡(luò)效率降低,所以協(xié)議棧一般會(huì)等數(shù)據(jù)量積累到一定程度再發(fā)送出去,那這個(gè)程度具體是啥樣?

首先,在以太網(wǎng)中,一個(gè)包的MTU(Maximum Transmission Unit,最大傳輸單元)是 1500 字節(jié),除去 TCP、IP 頭部的 40字節(jié),MSS(Maximum Segment Size,最大分段大小)就是 1460 字節(jié),但因?yàn)榧用苄枰?,頭部可能會(huì)增加,相對(duì)的 MSS 就會(huì)減少。當(dāng)緩存區(qū)內(nèi)的數(shù)據(jù)接近 MSS 時(shí)再發(fā)送,可以避免發(fā)送小包。但是如果數(shù)據(jù)量本來(lái)就很小,或者應(yīng)用程序發(fā)送數(shù)據(jù)的頻率很小,那協(xié)議棧就不得不等很長(zhǎng)時(shí)間,所以協(xié)議棧內(nèi)部還有一個(gè)定時(shí)器,一定時(shí)間之后就會(huì)將包發(fā)送出去。如果數(shù)據(jù)較小,那就幾個(gè)拼個(gè)車,放在一個(gè)包里發(fā)出去,如果數(shù)據(jù)很大,就要進(jìn)行拆分。大概是下面這樣:

 

本地一切就緒之后,協(xié)議棧就會(huì)將消息發(fā)送出去,這時(shí)還沒(méi)完,客戶端還要確保服務(wù)器收到了消息。我們一直都說(shuō) TCP 是面向連接的協(xié)議,因?yàn)樗梢约m正丟包錯(cuò)誤、連接失敗提示等等,使得傳輸更加可靠。那具體又是怎么樣的呢?

首先 TCP 模塊在拆分?jǐn)?shù)據(jù)時(shí)會(huì)先算好每一塊數(shù)據(jù)相當(dāng)于從頭開(kāi)始是第幾個(gè)字節(jié),然后將這個(gè)數(shù)字寫(xiě)入到 TCP 頭部的“序號(hào)”字段中,通過(guò)這個(gè)字段,接收方就能知道包有沒(méi)有丟失,比如一個(gè)消息長(zhǎng)度為 4380(1460 * 3),那么這條消息就被拆分到三個(gè)數(shù)據(jù)塊中,三個(gè)數(shù)據(jù)塊的 TCP 頭部的“序號(hào)”依次是 0、1460 和 2920,所以接收方先收到一個(gè)序號(hào)為 0 的包,再收到一個(gè)序號(hào)為 2920 的包,但是沒(méi)收到序號(hào)為 1460 的包,說(shuō)明這個(gè)包丟失了,現(xiàn)實(shí)中的序號(hào)為了安全不會(huì)從 0 開(kāi)始,而是以一個(gè)隨機(jī)數(shù)作為初始值。如果確認(rèn)沒(méi)有遺漏,那么接收方會(huì)將到目前為止收到的數(shù)據(jù)長(zhǎng)度加起來(lái),寫(xiě)入 TCP 的 “ACK 號(hào)”中發(fā)送給對(duì)方,注意 “ACK 號(hào)”與 ACK 標(biāo)記位不是一回事,前者是數(shù)字,后者就是一個(gè)比特的標(biāo)記位,但是 “ACK 號(hào)”只有在 ACK 標(biāo)記位為 1 是才有效。

斷開(kāi)連接

當(dāng)數(shù)據(jù)發(fā)送完畢后,一方(可能是客戶端,可能是服務(wù)端)就會(huì)發(fā)起斷開(kāi)連接過(guò)程。這個(gè)過(guò)程也是大家很熟悉的,即四次揮手。下面以客戶端發(fā)起斷開(kāi)請(qǐng)求為例:

  • 瀏覽器調(diào)用 Socket 庫(kù)關(guān)閉連接程序,客戶端的協(xié)議棧生成 TCP 頭部,將 FIN 標(biāo)記位設(shè)為 1,告訴服務(wù)器打算斷開(kāi)連接,后面不會(huì)再發(fā)送數(shù)據(jù),同時(shí)套接字也記錄斷開(kāi)連接操作;
  • 服務(wù)器收到 FIN 為 1 的 TCP 頭部時(shí),協(xié)議棧將套接字記錄為進(jìn)入斷開(kāi)操作狀態(tài),同時(shí)向客戶端發(fā)送一個(gè) ACK 號(hào),告訴客戶端已經(jīng)收到消息;
  • 服務(wù)器收到斷開(kāi)連接信息時(shí),可能還有數(shù)據(jù)沒(méi)有傳完,所以等待數(shù)據(jù)全部傳輸結(jié)束后,再發(fā)送一條 FIN 為 1 的信息,告訴對(duì)方也做了斷開(kāi)連接的準(zhǔn)備,但沒(méi)有斷開(kāi);
  • 一段時(shí)間后,客戶端返回確認(rèn)信號(hào),到此,連接結(jié)束。

 

以上就是輸入 URL 后大概發(fā)生的一些事情,但是從面試角度看,仍然還有很多部分沒(méi)有涉及。后續(xù)還會(huì)繼續(xù)更新這篇文章,添加一些重要內(nèi)容,這里先挖個(gè)坑:

  • 常見(jiàn)狀態(tài)碼解析;
  • HTTP 緩存;
  • 滑動(dòng)窗口;
  • 握手與揮手過(guò)程中的異常處理。

好,坑就挖這么多,再多怕自己不想填,等填完再繼續(xù)挖。 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2022-02-09 07:40:42

JavaScript前端面試題

2022-07-27 08:27:34

Call前端

2020-11-06 09:05:18

前端web開(kāi)發(fā)

2019-02-21 14:12:26

前端面試題Vue

2023-05-19 08:21:40

MarginCSS

2013-03-18 10:00:21

面試題程序員面試官

2021-02-02 06:12:39

JavaScript 前端面試題

2023-08-27 15:57:28

前端開(kāi)發(fā)

2022-07-08 08:21:26

JSbind 方法

2010-04-15 11:54:55

面試

2024-07-24 08:38:07

2014-07-28 14:00:40

linux面試題

2022-01-18 08:16:52

Web 前端JavaScript

2023-12-12 07:40:52

JavaScript面試題前端

2023-09-04 08:28:34

JavaScripforEach 循環(huán)

2020-07-09 09:08:24

Java系統(tǒng)故障

2019-11-20 15:00:53

JqueryAjax前端

2018-03-08 18:40:47

Java百度面試題

2021-06-27 22:48:28

Redis數(shù)據(jù)庫(kù)內(nèi)存

2021-03-04 09:35:54

thisJavaScript開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)