程序員的日常大戲”又來了。
事情是這樣的一位后端兄弟剛入職國企,寫了幾個接口,用了put和delete,結果前端同事卻跳出來說:“兄弟,這倆不能用,改成post吧!
不過人家前端同事是真的在找茬嗎?
其實人家真不是故意找事兒,確實在前端開發中很少使用put和delete接口。
為什么我們在和后端對接的時候,很少用PUT和DELETE接口,而是更多地使用POST和GET接口。
首先,我得先和大家解釋一下什么是HTTP請求方法。
HTTP請求方法有很多種,常見的有GET、POST、PUT、DELETE、PATCH等。這些方法其實就像我們平常在快遞公司寄包裹時選擇的服務類型:快遞、普通包裹、EMS等等,每種服務類型都有自己的用途和特點。
GET方法主要用于向服務器請求數據。比如,你想查看某個網頁內容,瀏覽器就會發起一個GET請求,把你請求的內容下載到本地展示出來。
GET請求的特點是“只讀”,不對服務器上的資源產生任何影響。這就像我們去圖書館查資料,只是在那兒讀書,不帶走也不更改任何書籍內容。
POST方法則用于向服務器提交數據。假如我們需要在網站上填寫一個表單,比如注冊賬戶、提交訂單等,就需要用到POST請求。POST請求的特點是“可寫”,可以在服務器上創建新的資源或對現有資源進行修改。
就好比我們去郵局寄信,把信件交給郵局,郵局會根據信件內容進行處理和投遞。
既然GET和POST這么常用,那PUT和DELETE是干嘛的呢?
PUT方法用于更新資源,而DELETE方法則用于刪除資源。聽起來也很有用,為什么在前端開發中很少用到它們呢?
PUT方法可以說是“更新大王”。當我們需要更新服務器上的資源時,比如修改用戶信息、更新文章內容等,就需要用到PUT請求。
然而,PUT請求有個特點:它通常要求客戶端發送完整的資源信息。舉個例子,如果我們需要更新用戶的郵箱地址,可能需要把整個用戶信息(包括用戶名、密碼、地址等)都發送給服務器。
這樣做雖然看起來很規范,但在實際開發中并不總是方便。
首先,前端開發需要額外處理更多的數據,這無形中增加了代碼的復雜性和工作量。
其次,PUT請求通常被認為是冪等的,意思是無論你發送多少次同樣的請求,服務器的資源狀態應該是一樣的。這對于一些需要部分更新的操作來說,未免有些不太靈活。
DELETE方法則用于刪除服務器上的資源。比如,你要刪除一個賬戶、移除一篇文章,就可以使用DELETE請求。但是DELETE請求也有它的問題。
首先,DELETE請求不安全。很多瀏覽器和防火墻會對DELETE請求進行嚴格限制,防止惡意用戶通過發送DELETE請求刪除不該刪除的數據。這就導致我們在前端開發中使用DELETE請求時,往往會遇到種種限制和麻煩。
其次,DELETE請求的可追溯性差。DELETE請求一旦成功,資源就被徹底刪除了,這樣一來,如果出問題了,很難追溯刪除的原因和時間。這對于一些需要審計和數據恢復的場景來說,DELETE請求顯然不是最好的選擇。
其實我之前在前端開發中也遇到過這種情況。記得有一次,我們團隊在開發一個電商平臺時,遇到了一個關于接口調用的問題。當時我們需要實現商品信息的更新和刪除功能,后端同事建議我們使用PUT和DELETE請求。
然而在實際開發中,我們發現PUT和DELETE請求在一些瀏覽器中會遇到兼容性問題,導致功能無法正常使用。
于是,我們決定改用POST請求來實現這些操作。
在POST請求中,我們通過增加一個操作類型的參數,來區分是更新還是刪除操作。這樣一來,不僅解決了兼容性問題,還簡化了前端代碼的實現。
所以選擇合適的HTTP請求方法,不僅可以提高開發效率,還能保證應用的穩定性和兼容性。
HTTP請求方法有很多種,每種方法都有其特定的用途和特點。
在前端開發中,GET和POST請求因為其簡單易用、兼容性好、安全性高等優點,成為了我們最常用的請求方法。
而PUT和DELETE請求雖然也很有用,但由于其復雜性和兼容性問題,在實際開發中相對少用。
最后,希望大家在今后的開發中,能夠靈活運用這些知識,打造出更加優秀和穩定的應用。
文公眾號來源:01二進制 作者:雇個城管打天下
記得在面試的時候也被問到這題,當時答得并不好,這道題目其實可以挖掘很多的知識點出來,建議閱讀!
前幾天有個學妹問我為什么在瀏覽器里面輸了網址就會顯示出來頁面,雖然這個現象很常見,但是要想解釋清楚確實有些小困難,當時也只是簡單的回答了她,現在想趁著這個機會好好整理下相關知識。整理完才覺得其實就和我們去一個地方找人是一個道理。所以說藝術源于生活卻又高于生活,技術同樣如此。
在回答這個問題前, 我們先來了解下我們平常說的那個網址到底是啥?
網址的學名叫做統一資源定位符(Uniform Resource Locator, 常縮寫為URL), 我們知道現在的互聯網其實就是由眾多資源所構成的一張巨大的網, 如何定位那些資源就是靠的URL, 因此我們也可以把URL理解為是網絡上資源的“門牌號“, 我們在瀏覽器中輸入網址, 就相當于開一輛車(瀏覽器)去找一個地址(URL)
1. 緩存查找
如果你要出門找一個地方, 第一想法肯定是先想這個地方你有沒有去過, 你要是去過的話那就不需要問人直接過去就好了。 我們的系統也是這么想的。 當你在瀏覽器中輸入了URL之后, 瀏覽器會先查看 瀏覽器緩存 中有沒有這個地址, 如果沒有那就再去 系統緩存, 如果系統緩存還沒有, 那就去路由器緩存找, 總之只要緩存中有, 就說明有這個資源, 那瀏覽器直接顯示出來就好了。
Tips: 這里說下 hosts文件 , hosts 是一個沒有擴展名的系統文件, 可以用記事本等工具打開, 其作用就是將一些常用的網址域名與其對應的IP地址建立一個關聯“數據庫”, 當用戶在瀏覽器中輸入一個需要登錄的網址時, 系統會首先自動從 hosts 文件中尋找對應的 IP 地址,一旦找到, 系統會立即打開對應網頁, 如果沒有找到, 則系統會再將網址提交 DNS 域名解析服務器進行IP地址的解析。 需要注意的是, hosts文件配置的映射是靜態的, 如果網絡上的計算機更改了請及時更新IP地址, 否則將不能訪問。
2. DNS 解析
如果你認得去那個地址的路自然是最好, 那如果你根本就沒去過那咋辦? 肯定會有人說導航, 但并不是所有的地方都是導航能搜到的, 這個時候我們自然而然就會想著去問路人了。 瀏覽器也是這樣的, 如果在本地緩存中沒有找到想要的資源, 那就只能去其他網絡上的機器中尋找我想要的資源了。 那你怎么知道你要的資源在那臺機器上? 這時, DNS就橫空出世了。
DNS(Domain Name System, 域名系統),DNS解析的過程就是尋找哪臺機器上有你需要資源的過程。當你在瀏覽器中輸入一個地址時, 例如 www.baidu.com, 其實這段URL并不是真正意義上的地址。 互聯網上每一臺計算機的唯一標識是它的 IP 地址(比如127.0.0.1就是我們本機的 IP 地址), 但是 IP 地址并不方便記憶(畢竟都是很長的數字串), 所以也就出現了網址(URL)這個玩意了, 目的就是為了方便普通用戶去尋找網絡上的其他計算機。 所以 DNS 實際上充當了一個翻譯的角色, 將網址翻譯成 IP 地址(就跟我想去南京大學, 問路的那個人告訴我南京大學在廣州路上是一個道理)。
2.1 DNS 解析過程
DNS解析其實是一個遞歸查詢的過程:
在上述過程中, 首先在本地域名服務器中查詢 IP 地址, 如果沒有找到, 本地域名服務器會向根域名服務器發送一個請求, 如果根域名服務器也不存在該域名時, 本地域名會向com頂級域名服務器發送一個請求, 依次類推下去。 直到最后找到目標網址所對應的 IP, 并將其緩存到本地, 以供下次使用。
2.2 DNS負載均衡
在講DNS負載均衡前先來看張圖片:
看到這可能就會有人犯嘀咕了, 我們不是 ping 的同一個網址嗎, 為啥兩次IP都不一樣?。?其實原因很簡單, 如果每次都一樣是否說明你請求的資源都位于同一臺機器上面, 那么這臺機器需要多高的性能和儲存才能滿足億萬請求呢? 其實真實的互聯網世界背后存在成千上百臺服務器, 大型的網站甚至更多。 但是在用戶的眼中, 它需要的只是處理他的請求, 哪臺機器處理請求并不重要。 DNS可以返回一個合適的機器的IP給用戶, 例如可以根據每臺機器的負載量, 該機器離用戶地理位置的距離等等, 這種過程就是DNS負載均衡, 又叫做DNS重定向。
再來舉個例子, 如果你在新街口用地圖搜南京大學, 返回給你的第一條數據可能就是南京大學鼓樓校區(因為距離最近), 但如果你是在仙林用地圖搜南京大學, 返回給你的第一條數據就有可能是南京大學仙林校區了。 DNS負載均衡簡單來說也是這個道理。
2.3 DNS 污染
DNS 污染(DNS cache pollution), 又稱域名服務器緩存投毒(DNS cache poisoning), 是指一些刻意制造或無意中制造出來的域名服務器數據包, 把域名指往不正確的IP地址。
某些網絡運營商為了某些目的, 對DNS進行了某些操作, 導致上網的用戶無法通過域名取得正確的IP地址。 某些國家或地區出于某些目的為了防止某網站被訪問, 而且其又掌握部分國際DNS根目錄服務器或鏡像, 也會利用此方法進行屏蔽。 (Google、 Facebook等)
至于如果防止DNS污染, 這里只說一個方法就是修改hosts文件, 其他的自行搜索吧。
3. TCP連接
其實在上面DNS解析的圖中就已經有了TCP連接的過程了:
我們通過DNS解析獲取到了網址所對應的IP地址后, 便需要發起TCP連接請求, 這里總共需要三次握手, 具體的過程就不贅述了, 可以查閱相關資料, 這里推薦劉欣老師的《TCP/IP 之 大明王朝郵差》, 以及大學計算機網絡課本里面的TCP相關章節。
4. HTTP 請求
握手成功后, 瀏覽器就可以向服務器發送http請求了, 請求數據包。 發送HTTP請求的過程就是構建HTTP請求報文并通過TCP協議中發送到服務器指定端口(HTTP協議80/8080, HTTPS協議443)。HTTP請求報文是由三部分組成: 請求行,請求報頭和請求正文。
4.1 請求行
格式如下:
Method RequestURL HTTPVersion CRLF
例如:
GET index . html HTTP / 1.1
常用的方法有: GET,POST,PUT,DELETE,OPTIONS,HEAD。
4.2 請求報頭
請求報頭允許客戶端向服務器傳遞請求的附加信息和客戶端自身的信息。
Tips:客戶端不一定特指瀏覽器, 有時候也可使用Linux下的CURL命令以及HTTP客戶端測試工具等。
常見的請求報頭有: Accept,AcceptCharset,AcceptEncoding,AcceptLanguage,ContentType,Authorization,Cookie,UserAgent等。
上圖是使用Chrome開發者工具截取的對百度的HTTP請求以及響應報文, 從圖中可以看出, 請求報頭中使用了Accept, AcceptEncoding, AcceptLanguage, CacheControl, Connection, Cookie等字段。 Accept 用于指定客戶端用于接受哪些類型的信息, AcceptEncoding 與 Accept 類似, 它用于指定接受的編碼方式。Connection 設置為 Keepalive 用于告訴客戶端本次 HTTP 請求結束之后并不需要關閉 TCP 連接, 這樣可以使下次 HTTP 請求使用相同的 TCP 通道, 節省 TCP 連接建立的時間。
5. 服務器響應
這部分對應的就是后端工程師眼中的 HTTP。 后端從在固定的端口接收到 TCP 報文開始, 這一部分對應于編程語言中的 socket。 它會對 TCP 連接進行處理, 對 HTTP 協議進行解析, 并按照報文格式進一步封裝成 HTTP Request對象, 供上層使用。 這一部分工作一般是由 Web 服務器去進行, 常用的Web服務器有 Tomcat, IIS 和 Netty 等等。
HTTP響應報文也是由三部分組成: 狀態碼, 響應報頭和響應報文。 篇幅原因這里就不詳細展開了。
6. 瀏覽器解析網頁信息
服務器返回給瀏覽器的文本信息, 通常是 HTML, CSS, JS, 圖片等文件, 那么瀏覽器是如何對澤瀉內容進行渲染呢? 通常是下面五個步驟:
不過這五個步驟在不同內核的瀏覽器中執行細節是不同的, 想深入了解的可以查閱相關資料, 這里推薦一篇文章:《瀏覽器渲染頁面過程與頁面優化》(https://segmentfault.com/a/1190000010298038)
瀏覽器是一個邊解析邊渲染的過程。 首先瀏覽器解析HTML文件構建DOM樹, 然后解析CSS文件構建渲染樹, 等到渲染樹構建完成后, 瀏覽器開始布局渲染樹并將其繪制到屏幕上。
JS的解析是由瀏覽器中的 JS 解析引擎完成的。 JS是單線程運行, 也就是說, 在同一個時間內只能做一件事, 所有的任務都需要排隊, 前一個任務結束, 后一個任務才能開始。 但是又存在某些任務比較耗時, 如IO讀寫等, 所以需要一種機制可以先執行排在后面的任務, 這就是: 同步任務(synchronous)和異步任務(asynchronous)。 JS的執行機制就可以看做是一個主線程加上一個任務隊列(task queue)。 同步任務就是放在主線程上執行的任務, 異步任務是放在任務隊列中的任務。 所有的同步任務在主線程上執行, 形成一個執行棧; 異步任務有了運行結果就會在任務隊列中放置一個事件; 腳本運行時先依次運行執行棧, 然后會從任務隊列里提取事件, 運行任務隊列中的任務, 這個過程是不斷重復的, 所以又叫做事件循環(Event loop)。 如下圖所示:
7. 總結
當上述步驟執行完成后我們便可在瀏覽器中看到一個完整的頁面了, 總結下其實就只有幾步:
其實簡單來看這幾個過程并不是很復雜, 但是每個步驟都可以深挖出一大堆的知識, 比如DNS的優化、頁面渲染的優化、 HTTPS等等非常多的東西, 這里考慮到篇幅以及科普效果很多東西都一筆帶過了。
微信公眾號【程序員喬戈里】 作者喬戈里,斜杠青年,哈工大本碩985 碩士,百度Java 研發工程師,目前致力于分享求職必備學習經驗、求職心得和成長感悟/技術文章。(關注公眾號送9000G 考研/python/C++/java/前端/小程序/微信公眾號/機器學習/人工智能資源)
者 | MageByte團隊
來源 | 碼哥字節(ID:MageByte)
頭圖 | CSDN 下載自東方IC
詳解輸入網址點擊回車,后臺到底發生了什么。透析 HTTP 協議與 TCP 連接之間的千絲萬縷的關系。掌握為何是三次握手四次揮手?time_wait 存在的意義是什么?全面圖解重點問題,再也不用擔心面試問這個問題。
大致流程
URL 解析,解析 http 協議、端口、資源地址。
DNS 查詢:首先查詢本地 host,再訪問 DNS 服務器將 域名解析成 ip 地址。
建立 TCP 連接。
服務器收到請求后處理,并且構造響應返回給客戶端。
客戶端接收 HTTP 報文響應。
渲染頁面,最后有可能會四次揮手斷開連接,也可能不會而是復用連接。
重點來了:
如何理解 TCP 的三次握手與四次揮手?每次握手客戶端與服務端是怎樣的狀態?
為何揮手會出現 2MSL,遇到大量 Socket 處在 TIME_WAIT 或者 CLOSE_WAIT 狀態是什么問題?
三次握手與四次揮手的過程是怎樣的?
HTTP 的報文格式又是怎樣的?
繼續閱讀本文,且聽碼哥字節答疑解惑,微信搜索 “碼哥字節”,關注公眾號更多硬核。
比如【碼哥字節】在思否發布的一篇文章的地址:https://segmentfault.com/a/1190000023475177。url 遵守的規則是這個樣子
scheme://host.domain:port/path/filename
每個名詞的含義如下解釋:
scheme 定義應用層協議類型,比如 http、https、 ftp 等;
host 定義域主機(http 的默認主機是 www);
domain 定義因特網域名,比如 segmentfault.com;
port 主機的端口,http 默認是 80, https 默認是 443;
path 服務器上的資源路徑;
filename - 定義文檔/資源的名稱;
瀏覽器不能直接通過域名找到服務器,只能通過 IP 地址。
那瀏覽器是如何通過域名查詢到我們輸入的 url 對應的 IP 呢?
瀏覽器緩存:按照一定頻率緩存 DNS 數據。
操作系統緩存:如果瀏覽器緩存好啊不到記錄則去操作系統中找。
路由緩存:路由器 DNS 緩存。
ISP 的 DNS 服務器:ISP 是互聯網服務提供商(Internet Service Provider)的簡稱,ISP 有專門的 DNS 服務器應對 DNS 查詢請求。
根服務器:ISP 的 DNS 服務器還找不到的話,它就會向根服務器發出請求,進行遞歸查詢(DNS 服務器先問根域名服務器.com 域名服務器的 IP 地址,然后再問 .baidu 域名服務器,依次類推)
通過域名解析出 IP 地址以后就要建立 TCP/IP 連接了。
TCP/IP 分為四層,每一層都會加上一個頭部再發送給下一層。到了接收方后,對應的每一層則把對應層的頭部解析拆除,丟上上一層,跟發送端的過程反過來。
瀏覽器從地址欄得到服務器 IP,接著構造一個 HTTP 報文,其中包括:
請求行包含請求方法、URL、協議版本
請求報頭(Request Header):由 “關鍵字: 值”對組成,每行一對,關鍵字與值使用英文 “:” 分割
請求體:請求參數,并不是所有的請求有又請求參數。一般 get 參數 的格式 name=tom&password=1234&realName=tomson,也可以將參數放在 body 里面。
在傳輸報文之前會先建立 TCP/IP 連接,也就是后面我們要說的三次握手。
在這一層解決了數據可靠傳輸、及流量控制、擁塞控制。
可靠傳輸
對于發送方發送的數據,接收方在接受到數據之后必須要給予確認,確認它收到了數據。如果在規定時間內,沒有給予確認則意味著接收方沒有接受到數據,然后發送方對數據進行重發。
TCP的可靠傳輸是通過確認和超時重傳的機制來實現的,而確認和超時重傳的具體的實現是通過以字節為單位的滑動窗口機制來完成。
TCP擁塞控制
TCP協議通過慢啟動機制、擁塞避免機制、加速遞減機制、快重傳和快恢復機制來共同實現擁塞控制。
流量控制
采用通知窗口實現對發送端的流量控制,通知窗口大小的單位是字節。TCP通過在TCP數據段首部的窗口字段中填入當前設定的接收窗口(即通知窗口)的大小,用來告知對方 '我方當前的接收窗口大小',以實現流量控制。
通信雙方的發送窗口大小由雙方在連接建立的時候商定,在通信過程,雙方可以動態地根據自己的情況調整對方的發送窗口大小。
將數據段打包,并加入源及目標的 IP 地址,并且負責尋找傳輸路線。判斷目標地址是否與當前地址處于同一網絡中,是的話直接根據 Mac 地址發送,否則使用路由表查找下一跳地址,以及使用 ARP 協議查詢它的 Mac 地址。
根據以太網協議將數據分為以“幀”為單位的數據包,每一幀分為兩個部分:
標頭:數據包的發送者、接受者、數據類型
數據:數據包具體內容
以太網規定了連入網絡的所有設備都必須具備“網卡”接口,數據包都是從一塊網卡傳遞到另一塊網卡,網卡的地址就是 Mac 地址。每一個 Mac 地址都是獨一無二的,具備了一對一的能力。
在傳輸層傳輸數據之前需要建立連接,也就是三次握手創建可靠連接。
首先建立鏈接前需要 Server 端先監聽端口,因此 Server 端建立鏈接前的初始狀態就是 LISTEN 狀態,這時 Client 端準備建立鏈接,先發送一個 SYN 同步包,發送完同步包后,Client 端的鏈接狀態變成了 SYN_SENT 狀態。Server 端收到 SYN 后,同意建立鏈接,會向 Client 端回復一個 ACK。
由于 TCP 是雙工傳輸,Server 端也會同時向 Client 端發送一個 SYN,申請 Server 向 Client 方向建立鏈接。發送完 ACK 和 SYN 后,Server 端的鏈接狀態就變成了 SYN_RCVD。
Client 收到 Server 的 ACK 后,Client 端的鏈接狀態就變成了 ESTABLISHED 狀態,同時,Client 向 Server 端發送 ACK,回復 Server 端的 SYN 請求。
Server 端收到 Client 端的 ACK 后,Server 端的鏈接狀態也就變成了的 ESTABLISHED 狀態,此時建連完成,雙方隨時可以進行數據傳輸。
在面試時需要明白三次握手是為了建立雙向的鏈接,需要記住 Client 端和 Server 端的鏈接狀態變化。另外回答建連的問題時,可以提到 SYN 洪水攻擊發生的原因,就是 Server 端收到 Client 端的 SYN 請求后,發送了 ACK 和 SYN,但是 Client 端不進行回復,導致 Server 端大量的鏈接處在 SYN_RCVD 狀態,進而影響其他正常請求的建連。可以設置 tcp_synack_retries = 0 加快半鏈接的回收速度,或者調大 tcp_max_syn_backlog 來應對少量的 SYN 洪水攻擊。
我們只要關注 80 端口與 13743 端口建立的連接斷開過程,瀏覽器通過 13747 端口發送 [FIN, ACK] 這里是不是跟很多網上看到的不一樣?
其實是客戶端在發送 [FIN] 報文的時候順帶發了一個 [ACK] 確認上次傳輸確認。
接著服務端通過 80 端口響應了 [ACK] ,然后立馬響應 [FIN, ACK] 表示數據傳輸完了,可以關閉連接。
最后瀏覽器通過 13743 端口 發送 [ACK] 包給服務端,客服端與服務端連接就關閉了。
具體流程如下圖抓包所示:
三次握手與四次揮手
客戶端:
SYN_SENT - 客戶端發起第 1 次握手后,連接狀態為 SYN_SENT ,等待服務端內核進行應答,如果服務端來不及處理(例如服務端的 backlog 隊列已滿)就可以看到這種狀態的連接。
ESTABLISHED - 表示連接處于正常狀態,可以進行數據傳送??蛻舳耸盏椒掌骰貜偷?SYN+ACK 后,對服務端的 SYN 單獨回復(第 3 次握手),連接建立完成,進入 ESTABLISHED 狀態。服務端程序收到第 3 次握手包后,也進入 ESTABLISHED 狀態。
FIN_WAIT_1 - 客戶端發送了關閉連接的 FIN 報文后,等待服務端回復 ACK 確認。
FIN_WAIT_2 - 表示我方已關閉連接,正在等待服務端關閉??蛻舳税l了關閉連接的 FIN 報文后,服務器發回 ACK 應答,但是沒進行關閉,就會處于這種狀態。
TIME_WAIT - 雙方都正常關閉連接后,客戶端會維持 TIME_WAIT 一段時間,以確保最后一個 ACK 能成功發送到服務器端。停留時長為 2 倍的 MSL (報文最大生存時間),Linux 下大約是 60 秒。所以在一個頻繁建立短連接的服務器上通??梢钥吹匠汕先f的 TIME_WAIT 連接。
服務端:
LISTEN - 表示當前程序正在監聽某個端口時。
SYN_RCVD - 服務端收到第 1 次握手后,進入 SYN_RCVD 狀態,并回復一個 SYN+ACK(第 2 次握手),再等待對方確認。
ESTABLISHED - 表示連接處于正常狀態,可以進行數據傳送。完成 TCP3 次握手后,連接建立完成,進入 ESTABLISHED 狀態。
CLOSE_WAIT - 表示客戶端已經關閉連接,但是本地還沒關閉,正在等待本地關閉。有時客戶端程序已經退出了,但服務端程序由于異?;?BUG 沒有調用 close函數對連接進行關閉,那在服務器這個連接就會一直處于 CLOSE_WAIT 狀態,而在客戶機已經不存在這個連接了。
LAST_ACK - 表示正在等待客戶端對服務端的關閉請求進行最終確認。
TIME_WAIT 狀態存在的理由:
劃重點了
可靠地實現 TCP 全雙工連接的終止 在進行關閉連接四路握手協議時,最后的 ACK 是由主動關閉端發出的,如果這個最終的 ACK 丟失,服務器將重發最終的 FIN,因此客戶端必須維護狀態信息允 許它重發最終的 ACK。如 果不維持這個狀態信息,那么客戶端將響應 RST 分節,服務器將此分節解釋成一個錯誤( 在 java 中會拋出 connection reset 的 SocketException)。因而,要實現 TCP 全雙工連接的正常終 止,必須處理終止序列四個分節中任何一個分節的丟失情況,主動關閉 的客戶端必須維持狀 態信息進入 TIME_WAIT 狀態。
允許老的重復分節在網絡中消逝 TCP 分節可能由于路由器異常而“迷途”,在迷途期間,TCP 發送端可能因確認超時而重發這個 分節,迷途的分節在路由器修復后也會被送到最終目的地,這個 原來的迷途分節就稱為 lost duplicate。在關閉一個 TCP 連接后,馬上又重新建立起一個相同的 IP 地址和端口之間的 TCP 連接,后一個連接被稱為前一個連接的化身 ( incarnation),那么有可能出現這種情況,前一 個連接的迷途重復分組在前一個連接終止后出現,從而被誤解成從屬于新的化身。為了避免 這個情 況,TCP 不允許處于 TIME_WAIT 狀態的連接啟動一個新的化身,因為 TIME_WAIT 狀 態持續 2MSL,就可以保證當成功建立一個 TCP 連接的時 候,來自連接先前化身的重復分組已 經在網絡中消逝。
另外回答斷鏈的問題時,可以提到實際應用中有可能遇到大量 Socket 處在 TIME_WAIT 或者 CLOSE_WAIT 狀態的問題。一般開啟 tcp_tw_reuse 和 tcp_tw_recycle 能夠加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被動關閉的一方存在代碼 bug,沒有正確關閉鏈接導致的。
簡單地說就是
保證 TCP 協議的全雙工連接能夠可靠關閉;
保證這次連接的重復數據段從網絡中消失,防止端口被重用時可能產生數據混淆;
深入分析下 HTTP 報文到底是什么玩意。數據傳輸都是通過 TCP/IP 協議負責底層的傳輸工作, HTTP 協議基本不用操心,所謂的 “超文本傳輸協議” 似乎不怎么例會 “傳輸” 這個事情,那 HTTP 的核心又是什么呢?
比圖 TCP 報文,它在實際要傳輸的數據之前附加了一個 20 字節的頭部數據,存儲 TCP 協議必須的額外信息,例如發送方的端口號、接收方的端口號、包序號、標志位等等。
有了這個附加的 TCP 頭,數據包才能夠正確傳輸,到了目的地后把頭部去掉,就可以拿到真正的數據。這個很容易理解,設置起點與終點,不同協議貼上不同的頭部,到了對應目的地就拆下這個頭部,提取真正的數據。
與 TCP/UDP 類似需要在傳輸數據前設置一些請求頭,不同的是 HTTP 是一個 “純文本” 的協議,所有的頭都是 ASCII 碼的文本,很容易看出來是什么。
再者就是他的請求報文與響應報文的結構基本一樣,主要三大部分組成:
起始行(Start Line):描述請求或者響應的基本信息。
Header:使用 key-value 的形式詳細說明報文信息。
空行。
消息正文(Entity):傳輸的數據,圖片、視頻、文本等都可以。
這其中前兩部分起始行和頭部字段經常又合稱為“請求頭”或“響應頭”,消息正文又稱為“實體”,但與“header”對應,很多時候就直接稱為“body”。
敲黑板了
HTTP 協議規定報文必須包含 Header,而且之后必須有一個 “空行”,也就是“CRLF”,十六進制的“0D0A”,可以沒有 “body”。
報文結構如下圖所示:
截取一段報文:
請求頭-起始行
請求行由請求方法字段、URL 字段和 HTTP 協議版本字段 3 個字段組成,它們用空格分隔。例如,GET / HTTP/1.1。
HTTP 協議的請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
GET 是請求方法, “/” 是請求的目標資源,“HTTP/1.1” 請求協議版本號。
GET / HTTP/1.1 翻譯成文字大概就是:“hello,服務器,我要請求根目錄下的默認文件使用的是 HTTP 1.1 協議版本”。
頭部 Header
第二部分就是 Header,組成形式是 key:value,使用自定義頭需要注意事項:
header 字段不區分大小寫,通常是首字母大寫;
字段名不允許有空格,可以使用 “-”,不能使用 “_”;
字段名必須緊接著 “:”,不能有空格,但是 “:” 后面可以有空格。
字段名順序沒有意義;
接收到響應文本 HTML,則開始執行瀏覽器渲染機制。
不同的瀏覽器渲染可能有所差異,但是基本按照以下步驟執行:
根據 HTML 解析 DOM 樹;
根據 CSS 解析出 CSS 規則樹;
結合 DOM 樹與 CSS 規則樹,生成渲染樹;
根據生成的渲染樹計算每個節點的信息;
根據節點信息繪制畫面展示給用戶。
點分享
*請認真填寫需求信息,我們會在24小時內與您取得聯系。