前端應該瞭解的計算機網路知識(一)
朋友們好啊,我是來亦何哀,剛才有朋友問我,發生什麼事了,給我發來幾張截圖,我一看,哦,原來是昨天,有兩個年輕人,一個禿頂,一個半禿頂,他們說,我在題海里,頭髮刷沒了,你能不能幫助治療一下,很快,就給我發來幾道題,我一看,我一個都不會做,看來搞不了窩裡鬥了,我還是學習東西吧。
DNS
DNS
(Domain Name System
,域名系統),就是平時我們說的域名,當我們輸入home.cnblogs.com
訪問網站。實際上是訪問了不同的域。其中”.”是DNS
命稱空間,用來分割不同域,home
(三級域)和cnblogs
(二級域)和com
(頂級域),
所以其實www.cnblogs.com
和cnblogs.com
如何根據域名查詢到ip
?
- 訪問客戶端的
DNS
快取:瀏覽器快取 -> 系統快取(host
) -> 路由器快取,所以通過修改系統hosts
檔案我們可以把域名改成本地的地址,進行除錯開發,對於經常訪問的網站,也可以直接設定到hosts
裡,加快訪問速度。 - 訪問
ISP DNS
伺服器(ISP
,網際網路服務提供商,有聯通電信移動等。如果你是電信網路,則進入電信的DNS
快取伺服器,以下簡稱本地),如果本地伺服器有,則直接返回;如果沒有,讓本地DNS
伺服器去逐個諮詢查詢。 - 本地去諮詢
DNS
根伺服器,DNS
根伺服器發現是.com
區域管理的,告訴本地去諮詢它。 - 本地去諮詢
.com
頂級域伺服器,.com
cnblogs.com
主區域的伺服器。 - 本地去諮詢
baidu.com
主域名伺服器,baidu.com
域伺服器查詢到對應的IP
地址,返回給本地。 - 本地
DNS
雲伺服器通知使用者對方IP
地址,同時快取這個IP
地址,下次就直接訪問了。
DNS
有關的網路效能優化
- 使用
DNS
預解析,可以通過用meta
資訊來告知瀏覽器, 我這頁面要做DNS預解析
<meta http-equiv="x-dns-prefetch-control" content="on" />
- 可以使用
link
標籤來強制對DNS
做預解析
<link rel="dns-prefetch" href="xxx" />
UDP
連線
使用者資料包協議(User Datagram Protocol
),簡稱UDP
,是基於IP
之上開發能和應用打交道的協議,通過IP
地址資訊把資料包傳送給指定的電腦,
每個想訪問網路的程式都需要繫結一個埠號,UDP
再通過埠號把資料包分發給正確的程式。
UDP
傳輸的缺陷:
- 資料包在傳輸過程容易丟失
- 大檔案傳輸中,
UDP
並不知道如何組成這些資料包,不知道如何還原成完整的檔案。
雖然UDP
不能保證資料可靠性,但是傳輸速度非常快,所以UDP
會應用在一些關注速度、但不那麼嚴格要求資料完整性的領域,如線上視訊、互動遊戲等。
TCP
連線
TCP
(Transmission Control Protocol
,傳輸控制協議)是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。在一個TCP
連線中,會有3個過程:
建立連線階段
這個階段是通過 “三次握手” 來建立客戶端和伺服器之間的連線。
TCP
提供面向連線的通訊傳輸。面向連線是指資料通訊開始先做好兩端之間的準備工作。
所謂三次握手,是指在建立一個TCP
連線時,客戶端和伺服器總共要傳送3個數據包來確認連線的建立。
三次握手主要作用是:
- 確認雙方的接收能力和傳送能力
- 指定自己的初始化序列號,為後面的可靠性做準備
三次握手的過程是:
剛開始客戶端處於Closed
的狀態,伺服器處於Listen
狀態。伺服器說你沒用,客戶端說我有用,然後說要試試。
SYN
(synchronous
建立聯機)、seq
(Sequence number
順序號碼)、小寫ack
(acknowledgement
確認)、大寫ACK
(Acknowledgement
標識位,可以通過它標識包的性質, [ACK
] or [SYN
] or [FIN
] )
- 客戶端傳送到伺服器,客戶端上來就是一個傳送
SYN
報文給伺服器,並且指明客戶端初始化序列號為ISN(c)
,即以SYN=1, seq=x
的形式傳送過去。此時客戶端處於SYN_SEND
狀態。 - 伺服器傳送給客戶端,伺服器全部防住了,怎麼防住的呢?自然是採用經典的接、化、發,接手收到客戶端的
SYN
和ISN(c)
,化手設定ACK = ISN(c) + 1
以及指明伺服器初始化序列號為ISN(s)
,然後以SYN=1, ACK=x+1, seq=y
的形式傳送給客戶端。 - 客戶端傳送到伺服器,防出去以後,自然是傳統比試,以點到為止,但是客戶端不講武德,設定
ACK = ISN(s) + 1
,將自身的ISN(c) + 1
,以ACK=y+1, seq=x+1
的形式傳送給伺服器,這就壞了,兩人結仇了,此時客戶端處於ESTABLISHED
階段,伺服器收到報文,也處於ESTABLISHED
階段。
記憶規律:
建立連線 => 建立連線與確認 => 再次確認
- 首先發一個建立連線
SYN=1
和一個順序號碼seq=x
。 - 被伺服器接住了,也傳送建立連線
SYN=1
,同時傳送確認將客戶端順序號碼+1返回ACK=x+1
,再帶上自己的服務端順序號碼seq=y
。 - 客戶端再發送確認將服務端順序號碼+1返回
ACK=y+1
,再將客戶端順序號碼也+1返回seq=x+1
。
問題:兩次握手不行嗎?
三次握手的目的:
- 客戶端傳送資料給伺服器,伺服器確認自己可以接受客戶端的請求。
- 伺服器傳送資料給客戶端,客戶端確認自己可以傳送資料給伺服器,也可以接受到伺服器的請求。
- 客戶端傳送資料給伺服器,伺服器確認自己可以傳送資料給客戶端。
如果採用兩次握手,客戶端傳送資料給伺服器,伺服器確認後就當連線開始,就很可能遇到下面這種情況:
- 客戶端傳送一次請求給伺服器……指定時間後沒響應再發了一個。
- 伺服器先接收到後一個建立連線的請求,然後前一個建立連線的請求,因為網路延遲等問題,在第二個之後達到了。
- 伺服器認為第二個請求是最新發的,於是向客戶端傳送確認報文段,同意建立連線,於是連線建立了(兩次握手)。
- 這時候客戶端還在等待最新的請求連線(第二次請求),自動忽略伺服器傳送的關於第一個請求連線的響應,也不傳送資料。
- 伺服器一直等待客戶端傳送資料,伺服器資源被佔用。
問題:三次握手過程中可以攜帶資料嗎?
答案:第三次握手的時候可以攜帶,第一第二次不可以攜帶。
原因:如果第一次可以攜帶資料的話,有可能是惡意攻擊伺服器。這時候釋放大量的資料,不理會伺服器的的承受能力,讓伺服器花費很多時間、記憶體空間接收報文。
第三次握手的時候,客戶端處於ESTABLISHED
狀態了,它可以建立連線並且知道伺服器的接收、傳送能力是正常的,所以可以攜帶資料了。
傳輸資料階段
此時客戶端和伺服器都處於ESTABLISHED
狀態。
這個階段中,接收端需要對每個資料包進行確認操作。即接收端在接收到資料包之後,需要傳送確認資料包給傳送端。
如果傳送端在規定時間內沒有接收到接收端的反饋確認訊息,那麼判斷丟包(資料包丟失),從而觸發自身的重發機制。
一個大的檔案在傳輸過程中會被拆分為多個小的資料包,接收端按照TCP
頭中的序號進行排序,保證組成完整的資料。
斷開連線階段
資料傳輸完畢之後,需要終止連線,通過四次揮手來保證雙方都能斷開連線。
由於TCP
連線是全雙工的,因此每個方向都必須單獨進行關閉。
這個原則是當一方完成它的資料傳送任務後就能傳送一個FIN
來終止這個方向的連線。收到一個FIN
只意味著這一方向上沒有資料流動,一個TCP
連線在收到一個FIN
後仍能傳送資料。
首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
四次揮手的過程是:
FIN
( finish
結束 )
- 客戶端傳送給伺服器,客戶端以
FIN=1, seq=u
的形式傳送給伺服器,表示需要關閉客戶端和伺服器的資料傳輸。此時客戶端處於FIN_WAIT
狀態。 - 伺服器傳送給客戶端,伺服器收到資訊,先返回
ACK
給客戶端,即以ACK=1, seq=v, ack=u+1
的形式返回給客戶端,表示收到客戶端報文了。此時伺服器處於CLOST_WAIT
狀態。 - 伺服器傳送給客戶端,伺服器等待一會,看客戶端還有沒有資料沒發過來,等處理完這些資料之後,也想斷開連線了,於是傳送
FIN
給客戶端,即以FIN=1, ACK=1, seq=w, ack=u+1
的形式傳送給客戶端。此時伺服器處於LAST_ACK
狀態。 - 客戶端傳送給伺服器,客戶端收到
FIN
之後,返回ACK
報文作為應答,即以ACK=1, ack=w+1, seq=u+1
的形式傳送給伺服器。此時客戶端處於TIME_WAIT
狀態。
過一陣子之後,客戶端確保伺服器收到自己的ACK
報文了,則變成CLOSED
狀態。伺服器接受到ACK
報文之後,就也處於CLOSED
狀態了。
記憶規律:
客戶端告知結束 => 伺服器確認 => 伺服器告知結束 => 客戶端確認
FIN=1, seq=u
=> ACK=1, ack=u+1, seq=v
=> FIN=1, seq=w, ACK=1, ack=u+1
=> ACK=1, seq=u+1, ack=w+1
問題:為什麼需要四次揮手?
因為伺服器接收到客戶端的關閉請求之後。
- 可能有一些資料因為網路延遲等問題沒有傳送到,直接關閉會導致這些資料沒有接收到;
- 可能伺服器也有一些資料要傳送給客戶端,要確保這些資料傳送完。
TCP
和UDP
的區別
TCP
是面向連線的。UDP
是無連線的,即傳送資料前不需要先建立連結。TCP
提供可靠的服務,也就是說,通過TCP
連線傳送的資料,無差錯,不丟失,不重複,且按序到達,因此適合大資料量的交換。UDP
盡最大努力交付,即不保證可靠交付,因此UDP
是不可靠的TCP
是面向位元組流。UDP
面向報文,並且網路出現擁塞不會使得傳送速率降低(因此會出現丟包,對實時的應用比如IP
電話和視訊會議等)。TCP
只能是1對1的。UDP
支援1對1,1對多。TCP
的首部較大為20位元組。而UDP
只有 8 位元組。