計算機網絡總結#
一、體系結構#
應用層
:應用層協議定義的是應用進程間通信和交互的規則,為特定應用程序提供數據傳輸服務,例如 HTTP、DNS 等。數據單位為報文運輸層
:運輸層的任務就是負責向兩台主機中進程之間的通信提供通用的數據傳輸服務 (TCP 或 UDP)網絡層
:把運輸層產生的報文段或用戶數據報封裝成分組或包進行傳送數據鏈路層
:將網絡層交下來的 IP 數據報組裝成幀,並在兩個相鄰結點間的鏈路上進行傳送物理層
:利用物理媒介以比特形式傳送數據
物理層信道復用技術#
基本概念#
信道,向某一個方向傳送信息的媒介,包括
- 單向信道:一方發送,一方接收,
單工
- 雙向交替信道:雙方都可發送消息,但不能同時進行,
半雙工
- 雙向同時信道:雙方可同時發送信息,
全雙工
復用,即信道共享,幾種常見的信道復用技術:頻分復用,時分復用,統計時分復用。通過復用器和分用器進行信號的復用和分用
信道復用技術#
1. 頻分復用 FDM
用戶在同樣的時間內占用不同的頻率帶寬而復用同一個信道
2. 時分復用 TDM
將時間劃分為相同的時分復用幀 TDM,在不同的時間占用相同的頻帶寬度,
**3. 統計時分復用 STDM **
改進的時分復用,按需動態分配時隙,而不是固定分配時隙 (時隙數小於連接在集中器上的用戶數,使得每次傳送的 STDM 幀中的分組都是滿的
4. 波分復用 WDM
光的頻分復用,利用在光線技術通信中;
5. 碼分復用 CDM
每個用戶在相同的時間使用相同的頻帶進行通信,但各用戶使用經過挑選的不同碼型,從而使得各用戶之間可以進行獨立的通信
數據鏈路層#
數據鏈路層的主要功能:
- 鏈路管理
- 幀同步
- 流量控制
- 差錯控制
- 將數據與控制信息區分開
- 透明傳輸
- 尋址
數據鏈路層的三個基本問題:封裝成幀
,透明傳輸
,差錯檢測
封裝成幀#
將 IP 數據報的前後分別添加首部和尾部構成幀,以便於接收端能夠在物理層的比特流中知道幀的開始和結束,即進行幀定界;
此外,首部和尾部還要添加許多控制信息,鏈路層協議規定了所能傳送的幀的數據部分長度上限,最大傳送單元 ——MTU
透明傳輸#
透明傳輸的概念是指在數據鏈路層傳輸時,所傳輸的數據在數據鏈路層沒有任何的阻擋,接收方所收到的數據和發送方發送的數據沒有任何差別,也就是說,數據鏈路層對其傳輸的數據幀是完全透明的;
字節填充:
在傳輸的過程中,為防止數據部分出現幀定界符,使得接收方誤以為收到的數據提前結束,所以采用轉義字符的方法,將在數據部分出現的控制字符前插入轉義字符,在接收方的數據鏈路層將插入的轉義字符刪除
零比特填充法:
只要發現 5 個連續 1,則立即填入一個 0,保證不出現 6 個連續 1
差錯檢測#
差錯檢測指的是在傳輸過程中產生的比特差錯;
** 誤碼率:** 一段時間內,傳輸錯誤的比特占傳輸總數的比率;
目前在數據鏈路層采用的差錯檢驗方式是循環冗餘檢驗;
注:
在數據鏈路層我們保證的是無比特差錯,而並無傳輸差錯,傳輸差錯還包含幀丟失
,幀重複
,幀失序
等;
二、IP 地址#
概述#
計算機要實現網絡通信,就必須要有一個用於快速定位的網絡地址。IP 地址就是計算機在網絡中的唯一身份 ID,與現實世界中快遞的配送需要有具體的住宅地址是一個道理。
IP 地址 = 網絡地址 + 主機地址 (又稱:主機號和網絡號組成)
網段劃分#
A 類地址:以 0 開頭,第一個字節範圍:0 - 127(1.0.0.0 - 126.255.255.255
);
B 類地址:以 10 開頭, 第一个字节范围:128 - 191(128.0.0.0 - 191.255.255.255
);
C 類地址:以 110 開頭, 第一个字节范围:192 - 223(192.0.0.0 - 223.255.255.255
);
Internet 上保留地址用於內部私有使用: 10.0.0.0 - 10.255.255.255
, 172.16.0.0 - 172.31.255.255
, 192.168.0.0 - 192.168.255.255
。
子網掩碼#
-
在劃分子網的時候,我們將本來屬於主機號的一部分劃分到網絡號中,為了便於區分哪部分是網絡號,哪部分是主機號,這就需要通過子網掩碼來實現
-
子網掩碼不能單獨存在,它必須結合 IP 地址一起使用。
-
子網掩碼只有一個作用,就是將某個 IP 地址劃分成網絡地址和主機地址兩部分。
子網掩碼的計算#
利用子網數來計算子網掩碼#
計算規則:
-
將子網數目轉化為二進制來表示
-
取得該二進制的位數,為 N
-
取得該 IP 地址的類子網掩碼,將其主機地址部分的前 N 位置 1 即得出該 IP 地址劃分子網的子網掩碼
如欲將 B 類 IP 地址 168.195.0.0 劃分成 27 個子網:
1)27=11011
2) 該二進制為五位數,N = 5
3) 將 B 類地址的子網掩碼 255.255.0.0 的主機地址前 5 位置 1,得到 255.255.248.0 即為劃分成 27 個子網的 B 類 IP 地址 168.195.0.0 的子網掩碼
利用主機數來計算子網掩碼#
計算規則:
-
將主機數目轉化為二進制來表示
-
如果主機數小於或等於 254(注意去掉保留的兩個 IP 地址),則取得該主機的二進制位數,為 N,這裡肯定 N<8。如果大於 254,則 N>8,這就是說主機地址將占據不止 8 位。
-
使用 255.255.255.255 來將該類 IP 地址的主機地址位數全部置 1,然後從後向前的將 N 位全部置為 0,即為子網掩碼值
如欲將 B 類 IP 地址 168.195.0.0 劃分成若干子網,每個子網內有主機 700 台:
- 700=1010111100
2) 該二進制為十位數,N = 10
3) 將該 B 類地址的子網掩碼 255.255.0.0 的主機地址全部置 1,得到 255.255.255.255 然後再從後向前將後 10 位置 0, 即為: 11111111.11111111.11111100.00000000 即 255.255.252.0。這就是該欲劃分成主機為 700 台的 B 類 IP 地址 168.195.0.0 的子網掩碼
三、UDP#
概述#
- 用戶數據報協議 UDP 只在 IP 的數據報服務之上增加了復用和分用的功能以及差錯檢測的功能。只有
面向無連接的報文
,不可靠傳輸
的特點。 - UDP 對應用層交下來的數據只添加首部,並進行特別的處理,就交給網絡層;
- 對網絡層傳遞上來的用戶數據報拆封首部後,原封不動的交給應用層
UDP 首部格式#
UDP 首部字段很簡單,由 4 個字段組成,每個字段的長度都是兩個字節,共 8 字節。
- 源端口號:在需要對方回信時選用,不需要時可全 0
- 目的端口號:這在終點交付報文時必須使用,不然數據交給誰呢?
- 長度: UDP 的長度,最小值為 8 字節,僅有首部
- 檢驗和: 檢測用戶數據報在傳輸過程是否有錯,有錯就丟棄。
在傳輸的過程中,如果接收方 UDP 發現收到的報文中的目的端口不存在,會直接丟棄,然後由網際控制報文協議 ICMP 給發送方發送 “端口不可達” 差錯報文
關於循環冗餘校驗法,詳見: CRC(循環冗餘校驗碼)簡介與實現解析
四、TCP#
TCP 協議作為傳輸層主要協議之一,是面向連接,端到端,可靠的全雙工通信,面向字節流的數據傳輸協議
TCP 報文段#
雖然 TCP 面向字節流,但 TCP 傳輸的數據單元卻是報文段。TCP 報文段分為TCP首部
和數據部分
,TCP 報文段首部的前20個字節
是固定的,後面有 4n 字節根據需要動態添加的選項,最大長度為 40 字節
-
源端口和目的端口
各占兩個字節,TCP 的分用功能也是通過端口實現的。 -
序號(Sequence Number)
占 4 個字節,範圍是 [0,232],TCP 是面向字節流的,每個字節都是按順序編號。例如一個報文段,序號字段是 201,攜帶數據長度是 100,那麼第一個數據的序號就是 201,最後一個就是 300。當達到最大範圍,又從 0 開始。 -
確認
號占 4 個字節,是期望收到對方下一個報文段的第一個字節的序號。若確認號 = N, 則表示序號 N 前所有的數據已經正確收到了。 -
數據偏移
占 4 位,表示報文段的數據部分的起始位置,距離整個報文段的起始位置的距離。間接的指出首部的長度。 -
保留
占 6 位,保留使用,目前為 0. -
URG(緊急
)當 URG=1, 表明緊急指針字段有效,該報文段有緊急數據,應儘快發送。 -
確認號(Acknowledgement Number)
僅當 ACK=1 時,確認號才有效,連接建立後,所有的報文段 ACK 都為 1。 -
PSH(推送)
接收方接收到 PSH=1 的報文段,會儘快交付接收應用經常,不再等待整個緩存填滿再交付。實際較少使用。 -
RST(重置)
RST=1 時,表明 TCP 連接中出現嚴重差錯,必須是否連接,再重連。 -
SYN(同步)
在建立連接時用來同步序號。當 SYN=1,ACK=0,則表明是一個連接請求報文段。SYN=1,ACK=1 則表示對方同意連接。TCP 建立連接用到。 -
FIN(終止)
用來釋放一個連接窗口。當 FIN=1 時,表明此報文段的發送方不再發送數據,請求釋放單向連接。TCP 斷開連接用到。 -
窗口
占 2 個字節,表示發送方自己的接收窗口,窗口值用來告訴對方允許發送的數據量。 -
校驗和
占 2 字節,檢驗和字段查驗範圍包括首部和數據部分。 -
緊急指針
占 2 字節,URG=1 時,緊急指針指出本報文段中的緊急數據的字節數(緊急字節數結束後為普通字節)。 -
選項
長度可變,最長可達 40 字節。例如最大報文段長度 MSS。MSS 指的是數據部分的長度而不是整個 TCP 報文段長度,MSS 默認為 536 字節長。窗口擴大,時間戳選項等
三次握手#
-
第一次:客戶端發送連接請求報文給服務端,其中 SYN=1,seq=x (代表客戶端的初始序列號),即
ISN(Initial Sequence Number, 初始序號)
。發送完畢後進入 SYN_END 狀態。 -
第二次:服務端接收到報文後,發回確認報文,其中 ACK=1,ack=x+1,因為需要客戶端確認,所以報文中也有 SYN=1,seq=y 的信息。發送完後進入 SYN_RCVD 狀態。
-
第三次: 客戶端接收到報文後,發送確認報文,其中 ACK=1,ack=y+1。發送完客戶端進入 ESTABLISHED 狀態,服務端接收到報文後,進入 ESTABLISHED 狀態。到此,連接建立完成
三次握手原因
避免資源被浪費掉。如果在第二步握手時,由於網絡延遲導致確認包不能及時到達客戶端,那麼客戶端會認為第一次握手失敗,再次發送連接請求,服務端收到後再次發送確認包。在這種情況下,服務端已經創建了兩次連接,等待兩個客戶端發送數據,而實際卻只有一個客戶端發送數據,就會造成資源浪費
四次揮手#
四次揮手指客戶端和服務端各發送一次請求終止連接的報文,同時雙方響應彼此的請求
-
第一次揮手:客戶端發送 FIN=1,seq=x 的包給服務端,表示自己沒有數據要進行傳輸,單面連接傳輸要關閉。發送完後,客戶端進入 FIN_WAIT_1 狀態。
-
第二次揮手:服務端收到請求包後,發回 ACK=1,ack=x+1 的確認包,表示確認斷開連接。服務端進入 CLOSE_WAIT 狀態。客戶端收到該包後,進入 FIN_WAIT_2 狀態。此時客戶端到服務端的數據連接已斷開。
-
第三次揮手:服務端發送 FIN=1,seq=y 的包給客戶端,表示自己沒有數據要給客戶端了。發送完後進入 LAST_ACK 狀態,等待客戶端的確認包。
-
第四次揮手:客戶端收到請求包後,發送 ACK=1,ack=y+1 的確認包給服務端,並進入 TIME_WAIT 狀態,有可能要重傳確認包。服務端收到確認包後,進入 CLOSED 狀態,服務端到客戶端的連接已斷開。客戶端等到一段時間後也會進入 CLOSED 狀態。
注:
- 默認情況下 (不改變 socket 選項),當你調用 close ( or closesocket,以下說 close 不再重複) 時,如果發送緩衝中還有數據,TCP 會繼續把數據發送完。
- 發送了 FIN 只是表示這端不能繼續發送數據 (應用層不能再調用 send 發送),但是還可以接收數據
四次揮手原因
由於 TCP 的連接是全雙工,雙方都可以主動傳輸數據,一方的斷開需要告知對方,讓對方可以進行後續相關操作,負責任的表現。
基於 TCP 傳輸的協議有:FTP(文件傳輸協議)
、Telnet(遠程登錄協議)
、SMTP(簡單郵件傳輸協議)
、POP3(和SMTP相對,用於接收郵件)
、HTTP協議
等
“三次握手,四次揮手” 補充#
ISN#
三次握手的一個重要功能是客戶端和服務端交換 ISN, 以便讓對方知道接下來接收數據的時候如何按序列號組裝數據。
如果 ISN 是固定的,攻擊者很容易猜出後續的確認號
ISN = M + F(localhost, localport, remotehost, remoteport)
M 是一個計時器,每隔 4 毫秒加 1。 F 是一個 Hash 算法,根據源 IP、目的 IP、源端口、目的端口生成一個隨機數值。要保證 hash 算法不能被外部輕易推算得出
TIME_WAIT 狀態詳解#
TIME_WAIT 狀態設置為2 * Maximum Segment Lifetime(報文最大生存時間)
,存在 TIME_WAIT 狀態的原因:
-
LAST_ACK 狀態下的 SOCKET 可能會因為超時未收到 ACK 報文而重發 FIN 報文,所以這個 TIME_WAIT 狀態的作用就是用來重發可能丟失的 ACK 報文
-
確保連接斷開,假如要關閉的這個鏈接後面在相同的 IP 地址和端口去建立一個新連接,可能會被誤認為是舊連接的新請求 (一個 tcp Session 由【源 IP、源端口、目的 IP、目的端口】四元組唯一決定),由於 TCP 報文段最大生存時間為 MSL,其保持 2MSL 時間可以確保網絡上兩個傳輸方向的尚未接收到的、遲到的報文段都已經消失,或被路由器丟棄,而 2MSL 時間後建立新的連接其絕不會收到原來連接的應用程序數據。這樣通過設置一個 2MSL 時長的 TIME_WAIT 狀態可以讓新的連接其絕不會收到原來連接的應用程序數據
序列號回繞#
因為 ISN 是隨機的,所以序列號容易就會超過 2^31-1. 而 tcp 對於丟包和亂序等問題的判斷都是依賴於序列號大小比較的,此時就出現了所謂的 tcp 序列號回繞(sequence wraparound)問題
半連接和全連接#
半連接隊列:
服務器第一次收到客戶端的 SYN 之後,就會處於 SYN_RCVD 狀態,此時雙方還沒有完全建立其連接,服務器會把此種狀態下請求連接放在一個隊列里,我們把這種隊列稱之為半連接隊列
全連接隊列:
已經完成三次握手,建立起連接的就會放在全連接隊列中,如果隊列滿了就有可能會出現丟包現象
其他例如syn flood攻擊
、Syn Cache技術
、Syn Cookie技術
、SYN Proxy防火牆
等詳細請參考:“三次握手,四次揮手” 你真的懂嗎?
TCP 可靠傳輸#
可靠的傳輸應該滿足:
-
傳輸的信道不產生差錯;
-
保證傳輸數據的正確性,無差錯、不丟失、不重複,並且按序到達
TCP 可靠傳輸的實現:
-
采用三次握手來建立 TCP 連接,四次握手來釋放 TCP 連接,從而保證建立的傳輸信道是可靠的。
-
TCP 采用了
ARQ協議
來保證數據傳輸的正確性 -
TCP 使用
滑動窗口協議
來保證接方能夠及時處理所接收到的數據,進行流量控制。 -
TCP 使用
慢開始
、擁塞避免
、快重傳
和快恢復
來進行擁塞控制
,避免網絡擁塞
滑動窗口協議#
滑動窗戶協議是指數據發送方有一個發送窗口,發送窗口範圍內的數據允許發送,隨著接收方傳來的確認信息以及通知的接收窗口的大小來動態調整發送窗口的起始位置以及大小
窗口的滑動有三種情況:
- 前沿向右移動,這種情況發生在數據發送並被確認時。
- 後沿向右移動,允許發送更多數據。這種情況發生在接收窗口增大或者網絡擁塞情況緩解時。
- 後沿向左移動,這種情況發生在接收方希望發送窗口縮小時,TCP 標準強烈不建議出現這種情況。因為發送方在收到縮小窗口的通知時,可能已經發送了一些縮小部分的數據,容易造成錯誤
- 窗口前沿無法向左移動,因為 TCP 會將窗口之外已經收到確認的數據清除出緩存
ARQ 協議#
ARQ 自動重傳請求(Automatic Repeat-reQuest)是一種在數據傳輸時,使用確認
(Acknoledgements,就是我們常說的ACK
,接收方發送一個消息,告訴發送方,自己是否正確接到了一个包體)和超時
(Timeouts,在收到一個確認消息之前,等待的一個確定的時間段)機制,在不可靠的網絡上,實現可靠的數據傳輸的錯誤控制方法策略,包括停止等待ARQ協議
和連續ARQ協議
,錯誤侦測(Error Detection)
、正面確認(Positive Acknowledgment)
、逾時重傳(Retransmission after Timeout)
與負面確認繼以重傳(Negative Acknowledgment and Retransmission)
等機制
停止等待 ARQ:
“停止等待” 是指每發送完一個分組就停止發送,等待對方確認,在收到對方確認後再發送下一個分組,有兩種錯誤情況
- 當接收方收到錯誤數據分組時,會直接丟棄分組。
- 發送方在一定時間沒有收到確認,則會重傳分組,即超時重傳
連續 ARQ 協議:
-
滑動窗口協議 與 自動重傳請求技術結合形成連續 ARQ 協議。連續 ARQ 協議根據超時重發數據方式的不同分為
後退N幀ARQ協議
和選擇重發ARQ協議
-
發送方每收到一個確認,就把發送窗口向前滑動一個分組的位置。
-
接收方一般都是采用
累積確認(ACK機制)
的方式。這就是說接收方不必對收到的分組逐個發送確認,而是可以在收到幾個分組後對按序到達的最後一個分組發送確認,這樣就表示:到這個分組為止的所有分組都已正確收到了
後退N幀 ARQ(Go-Back-N ARQ)
#
GBN 是在發送完一個數據幀後,不停下來等待確認幀,而是可以連續再發若干幀,邊發可以邊等待確認幀,如果收到了確認幀,又可以繼續發送數據幀, 由於減少了等待的時間,利用率就提高了。但是如果接收到錯誤幀的話,所有該幀後面的幀都要重發
選擇性重發/拒絕 ARQ (Selective Repeat/Reject ARQ)
#
相對於後退 N 幀 ARQ,在收到錯誤幀的情況下不需要再重傳所有的,只需要選擇錯誤的幀進行重發,進一步提高了復用率。但同時犧牲了空間,因為它需要將已經接收到的正确信息緩存下來,直到所有信息正確被接收到然後再發送確認收到
流量控制#
通過 TCP 連接發送數據,如果發送方發送數據很慢,容易造成資源浪費;如果發送方發送數據過快,接收方來不及接收會造成數據丟失。流量控制就是指在接收方能夠接收的範圍內,合理而又快速的發送數據。
基於滑動窗口的流量控制#
在 TCP 連接建立時,接收方會在確認報文段中給出自己接收窗口的大小。在每次發送確認報文時能夠根據情況動態調整接收窗口的大小,並將告知發送方。如下圖所示:
發送方發送序號從 1 開始的 100 字節的數據,接收方在確認報文中聲明自身的接收窗口大小為 300 字節。之後發送方發送 300 字節數據,接收方在確認報文中聲明自身接收窗口大小調整為 50 字節。發送方再發送 50 字節數據之後,收到接收方傳來的確認報文,在該報文中聲明接收窗口為 0。
在接收方接收窗口為 0 時,發送方不再發送數據,直到接收方發送確認報文表明窗口大小發生改變。可是這個確認報文不一定能夠被發送方接收到,如果一旦該確認報文丟失,雙方都將處於等待中,形成死鎖。為防止這種情況出現,TCP 規定在收到對方接受窗口為 0 時,啟動一個堅持定時器周期性的發送探測報文,以確定對方接收窗口為 0 的狀態是否改變
另外,TCP 標準規定:接收方接收窗口為 0 時,不再接收正常數據,但是可以接收零窗口探測報文段、確認報文段、攜帶緊急數據的報文段
擁塞控制#
TCP 進行擁塞控制常用的算法有四種:慢啟動
、擁塞避免
、快重傳
、快恢復
慢啟動#
TCP 為發送方維持一個擁塞窗口,記為 cwnd, 擁塞窗口的值跟 SMSS 有關,SMSS 為發送的最大報文段長度。
慢啟動算法規定:擁塞窗口初始化後,每收到一個對新報文的確認,擁塞窗口就加一個 SMSS 的大小。擁塞窗口以字節為單位,但是慢啟動以 SMSS 大小為單位增加。按照慢啟動算法,經過一輪傳輸,擁塞窗口就增大一倍,這是一種指數增長的關係
擁塞避免#
慢啟動算法除了維持擁塞窗口 cwnd 變量之外,還維持另一個變量慢啟動門限 ssthresh。當 cwnd 以指數增長的形式增長到大於或等於 ssthresh 時,就不再采用慢啟動算法,而是采用擁塞避免算法來進行擁塞控制。
擁塞避免算法規定:每次收到一個確認時將 cwnd 增加 1/cwnd 個 SMSS。即不再是像慢啟動算法那樣經過一輪傳輸 cwnd 翻倍了,而是經過一輪傳輸增加一個 SMSS。這是一種加性增長的關係,當擁塞發生時(超時或收到重複確認),cwnd 被設置為 1 個 SMSS。ssthresh 被設置為當前窗口大小的一半,但最少為 2 個報文段
總結就是:加性增,乘性減
快重傳#
如果個別報文段在網絡中丟失,網絡並沒有發生擁塞,這種情況下發送方收不到確認報文,在超時之後會重傳該報文。發送方誤以為網絡發生擁塞,錯誤的啟動慢開始算法,降低了傳輸效率。
采用快重傳算法可以讓發送方儘早知道個別報文段的丟失。快重傳算法要求接收方不要延時發送確認,即使收到失序的報文段也要立刻發送對已收到報文的重複確認。如下圖所示:
接收方收到 M1 之後發送對 M1 的確認報文,M2 報文丟失,之後接收方收到 M3、M4、M5 時每次都發送對 M1 報文的重複確認。快重傳算法規定當收到三次重複確認後,發送方就認為 M2 報文段丟失,立即重傳 M2 報文段,而不用等待超時再重傳,這樣可以避免發送方誤認為網絡發生擁塞
快恢復#
在快重傳算法執行後,發送方知道只是丟失個別報文,而不是網絡發生擁塞。之後並不會執行慢啟動算法,而是執行快恢復算法:調整門限值 ssthresh = cwnd/2,同時設置 cwnd = ssthresh + 3 SMSS。設置擁塞窗口的值為門限值加 3 個報文段是因為發送方收到三個確認報文,就認為有三個分組已經離開網絡到達接收方的緩存,這三個確認報文不再占用網絡資源,可以適當增大擁塞窗口的大小
擁塞控制和流量控制的區別#
-
擁塞控制:擁塞控制是作用於網絡的,它是防止過多的數據注入到網絡中,避免出現網絡負載過大的情況
-
流量控制:流量控制是作用於接收者的,它是控制發送者的發送速度從而使接收者來得及接收,防止分組丟失的
五、TCP 和 UDP 的區別#
- TCP 面向字節流,UDP 面向報文;
- TCP 面向連接(需要三次握手),UDP 面向非連接;
- TCP 提供可靠的數據傳輸服務,有丟包重傳機制且保證數據順序,UDP 可能會丟包也不保證數據順序
- 每一條 TCP 連接只能是點對點的;UDP 支持一對一,一對多,多對一和多對多的交互通信
- TCP 要求系統資源較多,UDP 較少
具體編程時的區別,socket () 的參數不同
- UDP Server 不需要調用 listen 和 accept
- UDP 收發數據用 sendto/recvfrom 函數
- TCP:地址信息在 connect/accept 時確定
- UDP:在 sendto/recvfrom 函數中每次均需指定地址信息
- UDP:shutdown 函數無效
六、HTTP 協議#
HTTP 協議是超文本傳輸協議的縮寫,英文是 Hyper Text Transfer Protocol。它是從 WEB 服務器傳輸超文本標記語言 (HTML) 到本地瀏覽器的傳送協議,基於 TCP/IP 通信協議來傳遞數據
報文格式#
常見請求頭#
Accept
:用於告訴服務器,客戶端支持的數據類型Accept-Charset
:用於告訴服務器,客戶端采用的編碼格式Accept-Encoding
:用於告訴服務器,客戶端支持的數據壓縮格式Accept-Language
:客戶端的語言環境Host
:客戶端通過這個頭告訴服務器,想訪問的主機名If-Modified-Since
:客戶端通過這個頭告訴服務器,資源的緩存時間Referer
:客戶端通過這個頭告訴服務器,它是從哪個資源來訪問服務器的(防盜鏈)User-Agent
:客戶端通過這個頭告訴服務器,客戶端的軟件環境Cookie
:客戶端通過這個頭可以向服務器帶數據Connection
:處理完這次請求後是否斷開連接還是繼續保持連接Date
:當前時間值
常見響應頭#
Location
: 表示重定向的地址,該頭和 302 的狀態碼一起使用。Server
: 表示服務器的類型Content-Encoding
: 表示服務器發送給瀏覽器的數據壓縮類型Content-Length
: 表示服務器發送給瀏覽器的數據長度Content-Language
: 表示服務器支持的語言Content-Type
: 表示服務器發送給瀏覽器的數據類型及內容編碼Last-Modified
: 表示服務器資源的最後修改時間Refresh
: 表示定時刷新Content-Disposition
: 表示告訴瀏覽器以下載方式打開資源(下載文件時用到)Transfer-Encoding
: 告訴瀏覽器數據的傳送格式Set-Cookie
: 表示服務器發送給瀏覽器的 cookie 信息(會話管理用到)Expires
: 告訴瀏覽器把回送的資源緩存多長時間 -1 或 0 則是不緩存Cache-Control
: no-cachePragma
: no-cache
服務器通過以上兩個頭,也就是控制瀏覽器不要緩存數據Connection
: 表示服務器和瀏覽器的連接狀態。close:關閉連接 keep-alive: 保存連接
請求狀態碼#
狀態碼分類#
- 1XX- 信息型,服務器收到請求,需要請求者繼續操作。
- 2XX- 成功型,請求成功收到,理解並處理。
- 3XX - 重定向,需要進一步的操作以完成請求。
- 4XX - 客戶端錯誤,請求包含語法錯誤或無法完成請求。
- 5XX - 服務器錯誤,服務器在處理請求的過程中發生了錯誤
常見請求狀態碼#
200
OK 請求已成功204
No Content 無內容,服務器成功處理了請求沒有返回任何內容301
Moved Permanently 被請求的資源已移動,永久重定向302
Found 已找到,臨時重定向304
Not Modified 未修改,客戶的緩存資源是最新的,要客戶端使用緩存400
Bad Request 客戶端請求有語法錯誤,不能被服務器所理解401
Unauthorized 未授權,未授權客戶機訪問數據403
Forbidden 禁止,沒有權限訪問404
Not Found 請求資源不存在,可能是輸入了錯誤的 URL405
Method Not Allowed 方法不允許406
Not Acceptable 請求的資源的內容特性無法滿足請求頭中的條件,因而無法生成響應實體500
Internal Server Error 內部服務器錯誤502
Bad Gateway 無效網關,作為網關或者代理的服務器執行請求時接收到無效的響應503
Service Unavailable 服務不可用,服務器由於維護或者負載過重未能應答504
Gateway Timeout 網關連接超時,網關或者代理的服務器無法在規定的時間內應答
Post 和 Get 請求的異同#
-
GET 請求的數據會附在 URL 之後(就是把數據放置在 HTTP 協議頭中),以?分割 URL 和傳輸數據,參數之間以 & 相連。POST 把提交的數據則放置在是 HTTP 包的包體中
-
Get 可提交的數據量較小 (因為數據附在 URL 之後)、而 Post 提交的數據量較大,瀏覽器和服務器會有不同的限制
-
Post 安全性比 Get 高,GET 的數據在 URL 中對所有人都是可見的;說 Get 是安全的指的僅僅是非修改信息,Get 用於獲取 / 查詢資源信息,Post 用於更新資源信息
-
GET 是幂等的,POST 不是
-
GET 編碼類型 application/x-www-form-url,POST 編碼類型 encodedapplication/x-www-form-urlencoded 或 multipart/form-data
-
GET 歷史參數保留在瀏覽器歷史中。POST 參數不會保存在瀏覽器歷史中
幂等性#
HTTP 方法的幂等性是指一次和多次請求某一個資源應該具有同樣的副作用。即:同一個請求,發送一次和發送 N 次效果是一樣的!
幂等的方法:GET、DELETE、PUT
PUT 與 POST 均是創建或更新,唯一不同是 POST 非幂等
http1.x/2.0#
http1.1#
-
引入了持久連接( persistent connection),即 TCP 連接默認不關閉,可以被多個請求復用,不用聲明 Connection: keep-alive。
-
引入了管道機制( pipelining),即在同一個 TCP 連接里,客戶端可以同時發送多個
-
請求,進一步改進了 HTTP 協議的效率。
-
新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
-
http 協議不帶有狀態,每次請求都必須附上所有信息。請求的很多字段都是重複的,浪費帶寬,影響速度
http2.0#
-
http/2 是一個徹底的二進制協議,頭信息和數據體都是二進制,並且統稱為 "幀"(frame):頭信息幀和數據幀。 避免 http1.x 在傳輸數據時明文傳輸內容容易導致的安全性問題
-
復用 TCP 連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,且不用按順序一一對應,避免了隊頭堵塞的問題,此雙向的實時通信稱為多工( Multiplexing)。
-
HTTP/2 允許服務器未經請求,主動向客戶端發送資源,即服務器推送。
-
引入頭信息壓縮機制( header compression) , 頭信息使用 gzip 或 compress 壓縮後再發送
https#
HTTPS 經由 HTTP 進行通信,利用 SSL/TLS 協議來加密數據包,是 HTTP 的安全版,與 http 主要區別:
- HTTPS 協議需要到 CA 申請證書
- HTTP 和 HTTPS 使用端口不一樣,前者是 80,後者是 443
- HTTP 協議運行在 TCP 之上,所有傳輸的內容都是明文,HTTPS 運行在 SSL/TLS 之上,SSL/TLS 運行在 TCP 之上,所有傳輸的內容都經過加密的
- HTTPS 可以有效的防止運營商劫持
七、瀏覽器輸入域名到展示頁面過程#
事件順序:
- DNS 域名解析:瀏覽器緩存 --> 操作系統緩存 --> 本地 host 文件 --> 路由器緩存 --> ISP DNS 緩存 --> 頂級 DNS 服務器 / 根 DNS 服務器,查找域名對應的 IP 地址
- 建立 TCP 連接: TCP 采用三次握手與服務器建立連接,提供可靠的傳輸服務
- 發送 HTTP 請求:通過 TCP 連接把 HTTP 報文發送給服務器
- 服務器處理請求並返回 HTTP 報文
- 瀏覽器渲染頁面:首先瀏覽器解析 HTML 文件構建 DOM 樹,然後解析 CSS 文件構建渲染樹,等到渲染樹構建完成後,瀏覽器開始佈局渲染樹並將其繪製到屏幕
涉及到的協議:
-
應用層:HTTP (WWW 訪問協議),DNS (域名解析服務)
DNS 維護著 域名 (domain name) 和 IP 地址 (IP address) 的對照表表,以解析消息的域名。 -
傳輸層:TCP (為 HTTP 提供可靠的數據傳輸),UDP (DNS 使用 UDP 傳輸)
-
網絡層:IP (IP 數據數據包傳輸和路由選擇),ICMP (提供網絡傳輸過程中的差錯檢測),ARP (將本機的默認網關 IP 地址映射成物理 MAC 地址)
八、session 和 cookie 區別#
-
cookie 數據存放在客戶的瀏覽器上,session 數據放在服務器上。
-
cookie 不是很安全,別人可以分析存放在本地的 COOKIE 並進行 COOKIE 欺騙
-
考慮到安全應當使用 session。
-
session 會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能。考慮到減輕服務器性能方面,應當使用 COOKIE。
-
單個 cookie 保存的數據不能超過 4K,很多瀏覽器都限制一個站點最多保存 20 個 cookie
補充#
session 在一定程度上依賴於 cookie。服務端執行 session 機制時會生成 session 的 id 值,這個 id 值會發送給客戶端,客戶端每次請求都會把這個 id 值放到 http 請求的頭部發送給服務端,而這個 id 值在客戶端會保存下來,保存的容器就是 cookie
九、長連接和短連接與 WebSocket#
長連接和短連接#
長連接和短連接區別#
在 HTTP/1.0 中,默認使用的是短連接。也就是說,瀏覽器和服務器每進行一次 HTTP 操作,就建立一次連接,但任務結束就中斷連接。
從 HTTP/1.1 起,默認使用長連接,用以保持連接特性。使用長連接的 HTTP 協議,會在響應頭設置:Connection:keep-alive
在使用長連接的情況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。Keep-Alive 不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如 Apache)中設定這個時間。實現長連接要客戶端和服務端都支持長連接。
HTTP 協議的長連接和短連接,本質上是 TCP 協議的長連接和短連接
長連接和短連接應用場景#
-
長連接多用於操作頻繁,點對點的通訊,而且連接數不能太多情況。每個 TCP 連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,次處理時直接發送數據包就 OK 了,不用建立 TCP 連接。 例如:數據庫的連接用長連接,如果用短連接頻繁的通信會造成 socket 錯誤,而且頻繁的 socket 創建也是對資源的浪費。
-
而像 WEB 網站的 http 服務一般都用短鏈接,因為長連接對於服務端來說會耗費一定的資源,而像 WEB 網站這麼頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。 所以並發量大,但每個用戶無需頻繁操作情況需用短連接好
短輪詢和長輪詢#
和短連接和長連接有本質區別。長、短連接是客戶端與服務端建立和保持 TCP 連接的機制;而長、短輪詢是指客戶端請求服務端,服務端給予應答的方式。
-
短輪詢:重複發送 Http 請求,查詢目標事件是否完成,優點:編寫簡單,缺點:浪費帶寬和服務器資源
-
長輪詢:在服務端 hold 住 Http 請求(死循環或者 sleep 等等方式),等到目標時間發生 (保持這個請求等待數據到來或者恰當的超時),返回 Http 響應。優點:在無消息的情況下不會頻繁的請求,缺點:編寫複雜
WebSocket#
WebSocket 連接建立#
客戶端瀏覽器首先要向服務器發起一個 HTTP 請求,這個請求和通常的 HTTP 請求不同,包含了一些附加頭信息,其中附加頭信息 “Upgrade: WebSocket
” 表明這是一個申請協議升級的 HTTP 請求
WebSocket 和 HTTP 長連接區別#
- HTTP1.1 通過使用 Connection進行長連接,HTTP 1.1 默認進行持久連接。在一次 TCP 連接中可以完成多個 HTTP 請求,但是對每個請求仍然要單獨發 header,Keep-Alive 不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如 Apache)中設定這個時間。
- websocket 的長連接,是一個真的全雙工,第一次 tcp 鏈路建立之後,後續數據可以雙方都進行發送,不需要發送請求頭,並且這個連接會持續存在直到客戶端或者服務器端的某一方主動關閉連接,與 HTTP 長連接不同,WebSocket 可以更靈活的控制連接關閉的時機,而不是 HTTP 協議的 Keep-Alive 一到,服務端立馬就關閉(這樣很不人性化)