Web開發應該知道的計算機網絡知識
前言
作為一名程序員,不可能不與網絡打交道?,F在我們的手機,電腦,不夸張地說,離開了網絡就是一塊“廢鐵”,它們的作用將大打折扣。本文的作用呢,主要是針對不是非網絡專業開發的人員準備的, 以’最短的時間,了解計網最多的知識’為前提起筆。
概述
先來了解下各種我們知道, 但是不太了解的專業名詞的意思
因特網
因特網
因特網是當今世界上最大的網絡,是”網絡的網絡”。 即因特網是所有網絡互連起來的一個巨型網絡。
因特網的組成:
- 邊緣部分 : 主機
- 核心部分 : 大量網絡和連接這些網絡的路由器(此路由器不是我們家用的路由器)
以太網
以太網是現在最常用的局域網通信協議, 以太網上傳輸的是MAC幀。由于以太網同一時間只允許一臺計算機發送數據, 所以必須有一套檢測機制, 那就是CSMA/CD協議:
- 多點接入 : 多臺計算機以多點接入的方式連接在一根總線上
- 載波監聽 : 不管是否正在發送, 每個站都必須不停地檢測信道
- 碰撞檢測 : 邊發送邊監聽
OSI
開放系統互連基本參考模型,只要遵守這個OSI標準, 任何兩個系統都能進行通信。 OSI是七層協議體系結構,而TCP/IP是一個四層協議體系結構, 于是我們采取折中的方法, 學習計算機網絡原理的時候往往用的是五層協議的體系結構 :物理層,數據鏈路層,網絡層,傳輸層和應用層。
協議體系結構
物理層
計算機的世界里只有0和1,正如你現在所看這篇文章的文字,存儲在計算機中也是一大串0和1的組合。 但是這些數字不能在真實的物理介質中傳輸的, 而需要把它轉換為光信號或者電信號,所以這一層負責將這些比特流(0101)與光電信號進行轉換。
如果沒有物理層, 那么也就不存在互聯網,不存在數據的共享,因為數據無法在網絡中流動。
數據鏈路層
數據在這一層不再是以比特流的形式傳輸, 而是分割成一個一個的幀再進行傳輸。
MAC地址
又稱計算機的硬件地址, 被固化在適配器(網卡)ROM上的占48位的地址。MAC地址可以用來唯一區別一臺計算機,因為它在全球是獨一無二的。
分組交換
由于數據在這次曾要被分割成一個一個的幀,由于不同的鏈路規定了不同的最大幀長,即MTU(最大傳輸單元), 凡是超出這個MTU的幀都必須被分塊。 例如一臺貨車一次能運輸5噸的貨物, 而有條公路限載重2噸,那么你只好分3次運輸。
網橋
網橋工作在數據鏈路層,根據MAC幀的目的地址對收到的幀進行轉發和過濾。
以太網交換機
實際上就是一個多接口的網橋, 以太網交換機的每個接口都直接與一個單個主機或另一個集線器相連, 可以很容易實現VLAN(虛擬局域網)
以太網的MAC幀
MAC幀的格式為 :
MAC幀格式
- 目的地址 : 接收方48位的MAC地址
- 源地址 : 發送方48位的MAC地址
- 類型字段 : 標志上一層使用的是什么協議, 0×0800為IP數據報
網絡層
如果只有數據鏈路層沒有網絡層,,數據就只能在同一條鏈路上傳輸,不能跨鏈路傳輸。有了網絡層,數據便能跨域不同的數據鏈路傳輸。
IP地址
IP地址又稱為軟件地址,存儲在計算機的存儲器上, IPv4地址為32位,IPv6地址為128位。
IP地址和MAC地址
- 網絡層以上使用IP地址, 數據鏈路層以下使用MAC地址
- IP地址是邏輯地址, MAC地址是物理地址
- IP分組中首部的源地址和目的地址在傳輸中不會改變, MAC幀中首部的源地址和目的地址每到一個路由器會改變一次
IP地址分類
IP地址 = {<網絡號>, <主機號>}
A類地址 : 0.0.0.0 ~ 127.0.0.0
B類地址 : 128.0.0.0 ~ 191.255.0.0
C類地址 : 192.0.0.0 ~ 223.255.255.0
劃分子網之后的IP地址
IP地址 = {<網絡號>, <子網號>, <主機號>}
例如某單位擁有一個B類IP地址, 145.13.0.0,但凡目的地址為145.13.x.x的數據報都會被送到這個網絡上的路由器R。內部劃分子網后變成 : 145.13.3.0, 145.13.7.0,145.13.21.0. 但是對外仍表現為一個網絡,即145.13.0.0. 這樣路由器R收到報文后,再根據目的地址發到對應的子網上。
子網掩碼
一般由一串1和一串0組成,不管網絡有沒有劃分子網,將子網掩碼和IP地址做按位與運算即可得出網絡地址。
所有的網絡都必須使用子網掩碼,同時在路由表中必須有子網掩碼這一欄。 如果一個網絡不劃分子網,那么該網絡的子網掩碼就是默認的子網掩碼。
A類地址的默認子網掩碼為255.0.0.0
B類地址的默認子網掩碼為255.255.0.0
C類地址的默認子網掩碼為255.255.255.0
盡管劃分子網增加了靈活性,但是卻減少了能夠連接在網絡上的主機總數。
構成超網的IP地址
IP地址 = {<網絡前綴>, <主機號>}
使用網絡前綴, 無分類域間路由選擇CIDR。
例如,128.14.35.7/20, 意思是前20位為網絡前綴,后12位為主機號。 另外,CIDR把網絡前綴相同的連續的IP地址組成一個”CIDR地址塊”。
地址掩碼 : CIDR使用32位的地址掩碼, 類似于子網掩碼。
IP數據報
在網絡層, 數據是以IP數據報(IP分組)的形式傳輸的
IP數據報的格式
首部前20字節為固定長度, 是所有IP數據報必備的. 后4字節是可選字段, 其長度可變。
IP數據報首部固定的字段分析:
- 版本號 : IP協議的版本, IPv4或IPv6。
- 首部長度 : 記錄了首部的長度,最大為1111, 即15個32位字長,即60字節。當首部長度不是4字節的整數倍時, 需要使用最后的填充字段加以填充。
- 服務類型 : 一般無用。
- 總長度 : 指首部和數據之和的長度, 最大為216-1 = 65535字節。但是由于數據鏈路層規定每一幀的數據長度都有最大長度MTU, 以太網規定MTU為1500字節,所以超出范圍的數據報就必須進行分片處理。
- 標識 : 每產生一個IP數據報,計數器就+1, 并將此值賦值給標識字段。 再以后需要分片的數據報中, 標識相同說明是同一個數據報。
- 標志 : 占3位, 最低位記為MF(More Fragment)。 MF = 1說明還有分片;MF = 0說明這已經是最后一個分片。 中間一位記為DF(Don’t Fragment),意思是不能分片。 只有當DF = 0時才允許分片。
- 段位移 : 又稱片位移, 相對于用戶數據字段的起點,該片從何處開始。 片位移以8個字節為偏移單位。 所以,每個分片的長度一定是8字節的整數倍。
- 生存時間 : TTL(Time To Live)。 數據報能在因特網中經過路由器的最大次數為255次, 每經過一個路由器則TTL – 1,為0時丟棄該報文。
- 協議 : 記錄該報文所攜帶的數據是使用何種協議。
- 首部檢驗和 : 只檢驗數據報的首部,不檢驗數據部分。 不為0則丟棄報文。
- 源地址和目的地址 : 不解釋。
IP層轉發分組的流程
每個路由器內部都維護一個路由表, 路由表包含以下內容(目的網絡地址, 下一跳地址)。
使用子網時分組轉發時,路由表必須包含以下三項內容:目的網絡地址, 子網掩碼和下一跳地址。
特定主機路由 : 對特定的目的地址指明一個路由
默認路由 : 不知道分組該發給哪個路由器時就發給默認路由。當一個網絡只有很少的對外連接時使用默認路由非常合適。
路由器的分組轉發算法
- 從數據報中拿到目的IP地址D, 得出目的網絡地址N
- 若N就是與此路由器直接相連的某個網絡地址, 則直接交付(不需要再交給其他路由器轉發, 直接找到該目的主機交付), 否則 -> (3)
- 若路由表中有目的地址為D的特定主機路由, 則把數據報傳給該路由器, 否則 -> (4)
- 若路由表中有到達網絡N的路由, 則把數據報傳給該路由器, 否則 -> (5)
- 若路由表中有默認路由, 則交給該路由器, 否則 -> (6)
- 報告轉發分組出錯
虛擬專用網VPN
因特網中的所有路由器對該目的地址是專用地址的數據報一律不轉發, 下面有3種專用地址(虛擬IP地址)
10.0.0.0 ~ 10.255.255.255
172.16.0.0 ~ 172.31.255.255
192.168.0.0 ~ 192.168.255.255
假設現在公司A有一個部門在廣州和另一個在上海, 而他們在當地都有自己的專用網. 那么怎么將這兩個專用網連接起來呢?
- 租用電信的通信線路為本機構專用, 但是太貴了
- 利用公用的因特網當做通信載體, 這就是虛擬專用網VPN
網絡地址轉換NAT
多個專用網內部的主機公用一個NAT路由器的IP地址, 在主機發送和接收IP數據報時必須先通過NAT路由器進行網絡地址轉換。
NAT路由器的工作原理
不僅如此, NAT還能使用端口號, 搖身一變成為網絡地址和端口轉換NAPT
ARP協議
ARP是解決同一個局域網上的主機或路由器的IP地址和MAC地址的映射問題, 即 IP地址 -> ARP -> MAC地址
每一個主機都有一個ARP高速緩存, 里面有本局域網上的各主機和路由器的IP地址到MAC地址的映射表. 以下是ARP的工作原理:
ARP的工作原理.jpg
那如果是跨網絡使用ARP呢?
- 在本網絡上廣播
- 未找到該主機, 則到路由器
- 路由器幫忙轉發(在另一網絡上廣播)
- 找到了則完成ARP請求, 未找到則返回(2)
傳輸層
這一層是重中之重, 因為數據鏈路層, 網絡層這兩層的數據傳輸都是不可靠的, 盡最大能力交付的. 什么意思的? 就是它們不負責提交給你的就是正確的數據. 然而這一層的TCP協議將要提供可靠傳輸
這一層主要重點是兩個協議 : UDP 和 TCP
用戶數據報協議UDP
UDP主要特點 :
- 無連接
- 盡最大努力交付
- 面向報文 : 應用層交下來的報文直接加上UDP頭部就往IP層扔, 不合并也不拆分
- 沒有擁塞控制
- 支持一對一, 一對多, 多對一和多對多的交互通信
- 首部開銷小, 只有8個字節
UDP首部
UDP首部格式
- 源端口 : 源端口號. 在需要對方回信時選用, 不需要則全0
- 目的端口 : 目的端口號. 這在終點交付報文時必須要使用到
- 長度 : UDP數據報的長度, 最小值為8(僅有首部)
- 檢驗和 : 與IP數據報只檢驗首部不同的是, UDP需要把首部和數據部分一起檢驗
傳輸控制協議TCP
TCP主要特點 :
- 面向連接的運輸層協議
- 每一條TCP連接只能有2個端點, TCP是點對點的
- 提供可靠交付
- 全雙工通信
- 面向字節流
TCP的工作流程
TCP字節流
TCP的連接
TCP連接的端點叫套接字(socket)
socket = (IP地址 : 端口號)
每一條TCP連接唯一地被通信兩端的兩個端點(socket)所確定. 即 :
TCP連接 ::= {socket1, socket2} = {(IP1 : port1), (IP2 : port2)}
TCP報文段的首部
TCP報文段的首部
- 源端口和目的端口 : 同UDP端口作用
- 序號 : 本報文段的數據的第一個字節的序號
- 確認號 : 期望收到對方下一個報文段的第一個數據字節的序號
若確認號 = N, 則表明 : 到序號N-1為止的所有數據都已正常收到
- 數據偏移 : TCP報文段的首部長度
- 保留 : 以后用, 目前為0
- 緊急URG : 若URG = 1時, 說明緊急指針字段有效, 告訴系統這是緊急數據, 應盡快傳送. 例如突然要中斷傳送
- 確認ACK : ACK = 1時確認號才有效, ACK = 0時確認號無效. TCP規定, 連接建立后所有傳送的報文段都必須把ACK置1
- 推送PSH : 若PSH = 1, 則接收方收到報文段之后不再等到整個緩存滿而是直接向上交付
- 復位RST : 當RST = 1, 說明TCP連接有嚴重錯誤, 必須釋放連接再重連
- 同步SYN : 在連接建立時用來同步序號. 當SYN = 1, ACK = 0時表明這是一個連接請求報文段, 對方若同意建立連接, 則在響應的報文段中置SYN = 1, ACK = 1
- 終止FIN : 當FIN = 1, 表明此報文段的發送方數據已發送完畢, 并要求釋放連接
- 窗口 : 告訴對方 : 從本報文段首部中的確認號算起, 接收方目前允許對方發送的數據量. 這是作為接收方讓發送方設置其發送窗口的依據
- 檢驗和 : 同UDP, 檢驗首部和數據部分
- 緊急指針 : 當URG = 1時有效, 指出緊急數據的末尾在報文段的位置
- 選項 : 最大可40字節, 沒有則為0
最大報文段長度MSS(Maximum Segment Size) : 每一個TCP報文段中數據字段的最大長度,若不填寫則為默認的536字節。
窗口
TCP中很重要的一個概念, 那就是窗口(發送窗口和接收窗口)
窗口
由于停止等待協議非常低效,于是衍生出窗口這一概念。上圖為發送方維持的發送窗口, 位于發送窗口的5個分組都可以連續發送出去而不需要等待對方的確認。每收到一個確認, 就把發送窗口前移一個分組的位置。這大大提高了信道利用率!
接收方不必發送每個分組的確認報文,而是采用累積確認的方式。也就是說, 對按序到達的最后一個分組發送確認報文。
超時重傳
如果發送方等待一段時間后, 還是沒收到 ACK 確認報文,就會啟動超時重傳。 這個等待的時間為重傳超時時間(RTO, Retransmission TimeOut)。
然而, RTO 的值不是固定的,這個時間總是略大于連接往返時間(RTT,Round Trip Time)。假設報文發送過去需要5秒,對方收到后發送確認報文回來也需要5秒,那么RTT就為10秒, 那這RTO就要比10秒要略大一些。那么超過RTO之后還沒有收到確認報文就認為報文丟失了,就要重傳。
流量控制
利用滑動窗口和報文段的發送時機來進行流量控制。
擁塞控制
發送方維持一個擁塞窗口cwnd, 發送窗口 = 擁塞窗口。
慢開始 : cwnd = 1, 然后每經過一個傳輸輪次就翻倍
擁塞避免 : 讓cwnd緩慢增大, 每經過一個傳輸輪次就+1
慢開始門限ssthresh :
當cwnd < ssthresh, 使用慢開始算法當cwnd > ssthresh, 使用擁塞避免算法當cwnd = ssthresh, 隨意
擁塞控制
只要判斷網絡出現擁塞, 把ssthresh設為當前發送擁塞窗口的一半(不能小于2),并把cwnd設為1,重新執行慢開始算法。
除了慢開始和擁塞避免算法外, 還有一組快重傳和快恢復算法 :
快重傳 : 接收方及時發送確認, 而發送方只要一連收到三個重復確認, 馬上重傳
快恢復 : 當發送方一連收到三個重復確認時, ssthresh減半, cwnd設為ssthresh.
TCP三次握手
TCP三次握手建立連接和四次揮手斷開連接是面試愛問的知識點。
TCP三次握手
Q : 為什么要三次握手, 兩次不可以嗎?
A : 試想一下, A第一次發送請求連接, 但是在網絡某節點滯留了, A超時重傳, 然后這一次一切正常, A跟B就愉快地進行數據傳輸了. 等到連接釋放了以后, 那個迷失了的連接請求突然到了B那, 如果是兩次握手的話, B發送確認, 它們就算是建立起了連接了. 事實上A并不會理會這個確認, 因為我壓根沒有要傳數據啊. 但是B卻傻傻地以為有數據要來, 苦苦等待. 結果就是造成資源的浪費.
更加接地氣的解釋就是 : A打電話給B
第一次握手 : 你好, 我是A, 你能聽到我說話嗎第二次握手 : 聽到了, 我是B, 你能聽到我說話嗎第三次握手 : 聽到了, 我們可以開始聊天了三次握手其實就是為了檢測雙方的發送和接收能力是否正常, 你說呢?
TCP四次揮手
TCP四次揮手
Q : 為什么要四次揮手, 而不是兩次, 三次?
A :
首先, 由于TCP的全雙工通信, 雙方都能作為數據發送方. A想要關閉連接, 必須要等數據都發送完畢, 才發送FIN給B. (此時A處于半關閉狀態)
然后, B發送確認ACK, 并且B此時如果要發送數據, 就發送(例如做一些釋放前的處理)
再者, B發送完數據之后, 發送FIN給A. (此時B處于半關閉狀態)
然后, A發送ACK, 進入TIME-WAIT狀態
最后, 經過2MSL時間后沒有收到B傳來的報文, 則確定B收到了ACK了. (此時A, B才算是處于完全關閉狀態)
PS : 仔細分析以上步驟就知道為什么不能少于四次揮手了.
Q : 為什么要等待2MSL(Maximum Segment Lifetime)時間, 才從TIME_WAIT到CLOSED?
A : 在Client發送出最后的ACK回復,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重復發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之后進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那么Client會重發ACK并再次等待2MSL。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回復所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那么Client推斷ACK已經被成功接收,則結束TCP連接。
更加接地氣的解釋 :
第一次揮手 : A告訴B, 我沒數據發了, 準備關閉連接了, 你要發送數據嗎第二次揮手 : B發送最后的數據第三次揮手 : B告訴A, 我也要關閉連接了第四次揮手 : A告訴B你可以關閉了, 我這邊也關閉了
應用層
應用層協議最著名的就是HTTP, FTP了, 還有一個重要的DNS
域名系統(DNS, Domain Name System)
DNS 能將域名(例如, www.jianshu.com)解析成IP地址。
域名服務器分類
- 根域名服務器 : 最高層次的域名服務器
- 頂級域名服務器 : 如其名
- 權限域名服務器 : 負責一個區的應服務器
- 本地域名服務器 : 主機發送DNS查詢請求就是發給它
DNS查詢
DNS查詢
- 主機向本地域名服務器的查詢一般都是采用遞歸查詢
- 本地域名服務器向根域名服務器的查詢通常是采用迭代查詢
遞歸查詢 : B問A廣州怎么去, A不知道, A就問C, C不知道就問D...直到知道了再一層一層轉告直到A告訴B. 迭代查詢 : B問A廣州怎么去, A不知道, A就告訴你可以去問C, 然后B就去問C, C不知道, C就告訴你可以去問D, 然后B就去問D...直到B知道為止
DNS查詢例子 : 域名為x.tom.com的主機想知道y.jerry.com的IP地址
- 主機x.tom.com先向本地域名服務器dns.tom.com進行遞歸查詢
- 本地域名服務器采用迭代查詢. 它先問一個根域名服務器
- 根域名服務器告訴它, 你去問頂級域名服務器dns.com
- 本地域名服務器問頂級域名服務器dns.com
- 頂級域名服務器告訴它, 你去問權限域名服務器dns.jerry.com
- 本地域名服務器問權限域名服務器dns.jerry.com
- 權限域名服務器dns.jerry.com告訴它所查詢的主機的IP地址
- 本地域名服務器把查詢結果告訴主機x.tom.com
PS : 該查詢使用UDP, 并且為了提高DNS查詢效率, 每個域名服務器都使用高速緩存.
URL
URL的格式 : <協議>://<主機>:<端口>/<路徑>, 端口和路徑有時可省略.
使用HTTP協議的URL : http://<主機>:<端口>/<路徑>, HTTP默認端口號是80
HTTP協議
HTTP是面向事務的, 即它傳輸的數據是一個整體, 要么全部收到, 要么全部收不到.
萬維網的工作過程
每一次HTTP請求就需要建立一次TCP連接和釋放TCP連接.
HTTP是無連接, 無狀態的. 每一次請求都是作為一次新請求.
HTTP/1.0 缺點 : 無連接, 每一次請求都要重新建立TCP連接, 所以每一次HTTP請求都要花費2倍RTT時間(一次TCP請求, 一次HTTP請求)
HTTP/1.1 : 使用持續連接, 即保持TCP連接一段時間.
HTTP/1.1持續工作的兩種工作方式 : 非流水線方式和流水線方式 非流水線方式 : 收到一個請求的響應再發下一個請求, 效率低, 浪費資源 流水線方式 : 能夠同時發送多個請求, 效率高
HTTP的GET和POST
GET 請求通常用于查詢、獲取數據,而 POST 請求則用于發送數據
GET 請求的參數在URL中, 因此絕不能用GET請求傳輸敏感數據, 而POST 請求的參數在請求頭中, 安全性略高于GET請求
ps : POST請求的數據也是以明文的形式存放在請求頭中, 因此也不安全
Cookie
萬維網使用Cookie來跟蹤用戶, 表示HTTP服務器和用戶之間傳遞的狀態信息.
Cookie工作原理 :
1. 用戶瀏覽某網站, 該網站的服務器為用戶產生一個唯一的識別碼,并以此為索引在服務器后端數據庫中產生一個項目
2. 返回給用戶的HTTP響應報文中添加一條 "Set-cookie",值為該識別碼,如1233。用戶的瀏覽器將該cookie保存起來,在用于繼續瀏覽該網站時發送的每一個HTTP請求都會有一行 Cookie: 123于是,這個網站就知道Cookie為123的這個用戶做了什么,為這個用戶維護一個獨立的列表(如購物車)。
當然,Cookie是把雙刃劍,方便的同時也帶有危險性,例如隱私泄露等, 用戶可以自行決定是否使用Cookie。
Session
Cookie是保存在客戶端上的,而Session是保存在服務器中。當服務器收到用戶發出的Cookie時, 會根據Cookie中的SessionID來查找對應的Session,如沒有則會生成一個新的SessionID返回給用戶。
總而言之,Cookie和Session就是同一樣東西存放地方不同而已。
HTTPS
HTTPS協議
HTTPS協議在HTTP協議的基礎上,在HTTP和TCP中間加入了一層SSL/TLS加密層, 解決了HTTP不安全的問題: 冒充, 篡改, 竊聽三大風險。