當咱們在瀏覽器的地址欄中輸入地址並回車後,瀏覽器可能會作一些預處理,好比 Chrome 會根據歷史統計來預估所輸入字符對應的網站,好比輸入了「bai」,根據以前的歷史發現會有很大的機率會訪問 www.baidu.com ,所以就會在輸入回車前就立刻開始創建 TCP 連接甚至渲染了,這裏面還有不少其它策略,感興趣的同窗推薦閱讀 High Performance Networking in Chrome(http://aosabook.org/en/posa/high-performance-networking-in-chrome.html)。html
接着是輸入 URL 後的「回車」,這時瀏覽器會對 URL 進行檢查,首先判斷協議,若是是 http 就按照 Web 來處理,另外還會對這個 URL 進行安全檢查,而後直接調用瀏覽器內核中的對應方法,好比 WebView 中的 loadUrl 方法。linux
在瀏覽器內核中首先會檢查緩存,而後設置 UA 等 HTTP 信息,接着調用不一樣平臺下的網絡請求的方法。chrome
瀏覽器和瀏覽器內核是兩個不一樣的概念,瀏覽器指的是 Chrome、Firefox,而瀏覽器內核則是 Blink、WebKit、Gecko等,瀏覽器內核只負責渲染,GUI 及網絡鏈接等跨平臺工做則是由瀏覽器實現的瀏覽器
由於網絡的底層實現與內核相關,因此在這裏須要針對不一樣平臺進行處理,從應用層角度來看主要是作兩件事情:緩存
經過 DNS 查詢 IP安全
接下來就分別介紹這兩方面的內容。服務器
DNS 查詢實際上是基於 UDP 來實現的,這裏咱們經過一個具體例子來了解它的查找過程,如下是使用 dig fex.baidu.com +trace 命令獲得的結果:網絡
1> dig fex.baidu.com +trace 2 3; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> fex.baidu.com +trace 4;; global options: +cmd 5. 11950 IN NS f.root-servers.net. 6. 11950 IN NS k.root-servers.net. 7. 11950 IN NS l.root-servers.net. 8. 11950 IN NS m.root-servers.net. 9. 11950 IN NS b.root-servers.net. 10. 11950 IN NS c.root-servers.net. 11. 11950 IN NS e.root-servers.net. 12. 11950 IN NS a.root-servers.net. 13. 11950 IN NS g.root-servers.net. 14. 11950 IN NS d.root-servers.net. 15. 11950 IN NS i.root-servers.net. 16. 11950 IN NS h.root-servers.net. 17. 11950 IN NS j.root-servers.net. 18;; Received 251 bytes from 192.168.0.1#53(192.168.0.1) in 12 ms 19 20com. 172800 IN NS a.gtld-servers.net. 21com. 172800 IN NS b.gtld-servers.net. 22com. 172800 IN NS c.gtld-servers.net. 23com. 172800 IN NS d.gtld-servers.net. 24com. 172800 IN NS e.gtld-servers.net. 25com. 172800 IN NS f.gtld-servers.net. 26com. 172800 IN NS g.gtld-servers.net. 27com. 172800 IN NS h.gtld-servers.net. 28com. 172800 IN NS i.gtld-servers.net. 29com. 172800 IN NS j.gtld-servers.net. 30com. 172800 IN NS k.gtld-servers.net. 31com. 172800 IN NS l.gtld-servers.net. 32com. 172800 IN NS m.gtld-servers.net. 33com. 86400 IN DS 30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766 34com. 86400 IN RRSIG DS 8 1 86400 20200625050000 20200612040000 48903 . OwfRn9tBOE2btL/z3HG5PQVyTXu2OUcZGLi9svkHFV0tomeI1p9bHhqr GF/UDjf5a8VXNRoaSsSEQfgqwJT3UAOANK1vb3e+5jH2bV3Hg6/MAGG0 SuBfKv8Y1fjGgiLNC3NKmTWJ28WABHngymnGDpuqoC6xKmkVoD14ON7E uHbBGxC0Uxt6D5R3WfbAAfbzZXzyPcD3WK1OpGaL6ASMB2xvdAZIkp/Z l8QDmqZd86RX7haiVhxVG0mMrWxsN7XL2jVyRRFFl9UkApMk9/thPwNK Rgkd4BPCvMPZTvsb+mPZA4InLxP6oPliZQm5sIWH8fEiyS+LgEReROzG sqrpyw== 35;; Received 1173 bytes from 198.97.190.53#53(h.root-servers.net) in 206 ms 36 37baidu.com. 172800 IN NS ns2.baidu.com. 38baidu.com. 172800 IN NS ns3.baidu.com. 39baidu.com. 172800 IN NS ns4.baidu.com. 40baidu.com. 172800 IN NS ns1.baidu.com. 41baidu.com. 172800 IN NS ns7.baidu.com. 42CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q1GIN43N1ARRC9OSM6QPQR81H5M9A NS SOA RRSIG DNSKEY NSEC3PARAM 43CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20200618045106 20200611034106 39844 com. nL7GSwad11x22Ff4/a3sjIA27DplTa0SZWNb9jnTs0+PYEehVKCT4a2g TWgi5YHeqolDbwsK9oy7Hy1ZO3yhlhWUUAIyE5DE+iKuJCnD6fIvmXdq lXsBBvUHK6wtHzIAPJ8PbCAl/PwSNjpZUZvv4YcEtLWU14yTsPPAM/wB BxatwSt88sQrwYrLKqjnojEsmKVX1yi98pdT87BI/zKxzQ== 44HPVU6NQB275TGI2CDHPDMVDOJC9LNG86.com. 86400 IN NSEC3 1 1 0 - HPVVN3Q5E5GOQP2QFE2LEM4SVB9C0SJ6 NS DS RRSIG 45HPVU6NQB275TGI2CDHPDMVDOJC9LNG86.com. 86400 IN RRSIG NSEC3 8 2 86400 20200619061821 20200612050821 39844 com. Iz4sOw47dg/aDbs/T9JSAXDiE88bqoj/kYbDQW5dO9NnQicyC5ZqEj0o l1hxJHirVmJtCIXevkSy3eH1rrOH/Ni+oLlWZEBzQnucFK1C4WdBylF2 0OsgaG/AyHSD+9tWgMcQY+i28WBpxmxXvDLHY0oWb89UHMpcduqCh5+n YXnbOHzjvaER/hX1ljveDo0z+HJIBtgY6/0NeFFY0ZWkcA== 46;; Received 761 bytes from 192.43.172.30#53(i.gtld-servers.net) in 248 ms 47 48fex.baidu.com. 600 IN CNAME sugar.n.shifen.com. 49n.shifen.com. 86400 IN NS ns5.n.shifen.com. 50n.shifen.com. 86400 IN NS ns2.n.shifen.com. 51n.shifen.com. 86400 IN NS ns4.n.shifen.com. 52n.shifen.com. 86400 IN NS ns3.n.shifen.com. 53n.shifen.com. 86400 IN NS ns1.n.shifen.com. 54;; Received 241 bytes from 112.80.248.64#53(ns3.baidu.com) in 32 ms
能夠看到這是一個逐步縮小範圍的查找過程,首先由本機所設置的 DNS 服務器( 192.168.0.1 )向 DNS 根節點查詢負責 .com 區域的域務器,而後經過其中一個負責 .com 的服務器查詢負責 baidu.com 的服務器,最後由其中一個 baidu.com 的域名服務器查詢 www.baidu.com 域名的地址。socket
你在查詢某些域名的時會可能會發現和上面不同,最後將會看到有個奇怪的服務器搶先返回結果。。。tcp
這裏爲了方便描述,忽略了不少不一樣的狀況,好比 127.0.0.1 其實走的是 loopback,和網卡設備不要緊;好比 Chrome 會在瀏覽器啓動的時預先查詢 10 個你有可能訪問的域名;還有 Hosts 文件、緩存時間 TTL(Time to live)的影響等。
有了 IP 地址,就能夠經過 Socket API 來發送數據了,這時能夠選擇 TCP 或 UDP 協議,具體使用方法這裏就不介紹了,推薦閱讀 Beej’s Guide to Network Programming(http://beej-zhcn.netdpi.net/)。
HTTP 經常使用的是 TCP 協議,因爲涉及到 TCP 協議的具體細節的資料很容易就能找到,因此本文就不贅述了,只在這裏談一下 TCP 的 隊首阻塞 問題:假設客戶端發送了 3 個 TCP 片斷(segments),編號分別是 一、二、3,若是編號爲 1 的包傳輸時丟了,那麼即使編號 2 和 3 已經到達也只能等待,由於 TCP 協議須要保證前後順序,這個問題在 HTTP pipelining 下更嚴重,由於 HTTP pipelining 可讓多個 HTTP 請求經過一個 TCP 發送,好比發送兩張圖片,可能第二張圖片的數據已經全收到了,但還得等第一張圖片的數據傳到。
爲了解決 TCP 協議的性能問題,Chrome 團隊提出了 QUIC 協議,它是基於 UDP 實現的可靠傳輸,比起 TCP,它能減小不少往返(round trip)時間,還有前向糾錯碼等功能。目前 Gmail、Google Search、blogspot、Youtube 等幾乎大部分 Google 產品都在使用 QUIC,你能夠在 Chrome 中的 chrome://flags/#enable-quic 頁面找到它的配置。
雖然國內不少大廠也在研究 QUIC 的應用,但離大範圍普及還有較長的一段距離,由於若是針對 TCP 進行優化,須要升級系統內核。
瀏覽器對同一個域名有鏈接數是有限制得,[通常是 6 個(http://www.browserscope.org/?category=network&v=top),Chrome 團隊曾作過實驗,發現從 6 改爲 10 後性能反而降低了,形成這個現象的因素有不少,如創建鏈接的開銷、擁塞控制等問題,而像 SPDY、HTTP 2.0 協議儘管只使用一個 TCP 鏈接來傳輸數據,但性能反而更好,並且還能實現請求優先級。
另外,由於 HTTP 請求是純文本格式的,因此在 TCP 的數據段中能夠直接分析 HTTP 的文本。
前面說到瀏覽器的跨平臺庫經過調用 Socket API 來發送數據,那麼 Socket API 是如何實現的呢?
以 Linux 爲例,它實如今 socket.c(http://lxr.linux.no/linux+v3.14.4/net/socket.c) 中,若是你想深刻研究一下,推薦看 Linux kernel map(http://www.makelinux.net/kernel_map/),它標註出了關鍵路徑的函數,方便學習從協議棧到網卡驅動的實現。
接下來若是繼續介紹 IP 協議和 MAC 協議可能會把你們搞暈,因此下面用 tcpdump 來經過具體例子講解,如下是在請求百度首頁時抓取到的網絡數據:
能夠看到最前面的三次通訊是 TCP 協議的三次握手過程,在第四次通訊中被選中的部分爲 HTTP 協議(Hypertext Transfer Protocol),在 HTTP 以前有 54 字節(0x36),這就是底層網絡協議所帶來的開銷,咱們接下來對這些協議進行分析。
在 HTTP 之上是 TCP 協議(Transmission Control Protocol),它的具體內容以下圖所示:
經過底部的二進制數據,能夠看到 TCP 協議是加在 HTTP 文本前面的,它有 20 個字節,其中定義了本地端口(Source port)和目標端口(Destination port)、順序序號(Sequence Number)、窗口長度等信息,如下是 TCP 協議各個部分數據的完整介紹:
具體每一個字段的做用這裏就不介紹了,感興趣的同窗能夠經過閱讀 RFC 793(http://tools.ietf.org/html/rfc793),並結合抓包分析來理解。
須要注意的是,在 TCP 協議中並無 IP 地址信息,由於這是在上一層的 IP 協議中定義的,以下圖所示:
IP 協議一樣是在 TCP 前面的,它也有 20 字節,在這裏指明瞭版本號(Version)爲 4,源(Source) IP 爲 192.168.1.106,目標(Destination) IP 爲 119.75.217.56,所以 IP 協議最重要的做用就是肯定 IP 地址。
由於 IP 協議中能夠查看到目標 IP 地址,因此若是發現某些特定的 IP 地址,某些路由器就會。。。
可是,光靠 IP 地址是沒法進行通訊的,由於 IP 地址並不和某臺設備綁定,好比你的筆記本的 IP 在家中是 192.168.0.11,但到公司就變成 10.0.11.11 了,因此在底層通訊時須要使用一個固定的地址,這就是 MAC(media access control) 地址,每一個網卡出廠時的 MAC 地址都是固定且惟一的。
所以再往上就是 MAC 協議,它有 14 字節,以下所示:
當一臺電腦加入網絡時,須要經過 ARP 協議告訴其它網絡設備它的 IP 及對應的 MAC 地址是什麼,這樣其它設備就能經過 IP 地址來查找對應的設備了。
如今咱們搞清了標題中的問題,不過這裏面還有大量的細節沒介紹,建議你們經過下面的書籍進一步學習。