????????小猿的某同事不甘于現狀,近期到處投簡歷面試。某天,小猿只見某灰頭土臉、唉聲嘆氣,于是小猿本著看熱鬧不嫌事兒大的心態,一臉壞笑湊上去問:“大佬,最近面試咋樣,是不是都拿好幾個offer了~^_^”,某答道:“什么呀,面個試咋就這么難,一道面試題硬是讓面試官扯出了整個計算機網絡知識圖譜,也是沒誰了~”,小猿好奇問:“啥題,啥題~”,某答:“爛大街的一道題,面試前也準備了,唉,你說為啥面試官就能從這道題目扯出一堆題目...”(此處省略一萬字)
????????接下來小猿就給大家說說某遇到的這道題,還有它牽扯出的整個計算機網絡的知識圖譜。廢話不多說,直接上題目
????????題目描述一:請說說HTTP請求的整個過程
????????題目描述二:當你在瀏覽器中輸出某個URL,按下回車后都經歷了什么樣的流程
????????題目描述三:請簡單介紹一下HTTP是怎么工作的
????????相信各位猿對這道題應該并不陌生,而且網上一搜一堆的講解與答案,但是某遇到的這個大牛面試官,卻可以從某的回答中延伸出更多的問題,如果想要過關,還是要對整個計算機網絡的知識體系有比較深刻的理解才行。下面先貼出小猿對這個題目的理解和可能從這道題目引出的計算機網絡的知識點,然后小猿對這些知識點慢慢的給大家分析。
小猿對題 目的理解:
DNS解析:如果URL中是網址,需要向對這個網址進行域名解析,得到相應的IP地址,請求會逐層查詢DNS緩存得到目的IP地址(DNS緩存由近到遠依次是:瀏覽器緩存、系統緩存、路由器緩存、IPS服務器緩存、根域名服務器緩存、頂級域名服務器緩存)
TCP連接:根據IP地址和斷開,找到對應的服務器,通過TCP的三次握手建立連接
發送HTTP請求:建立TCP連接后發起HTTP請求
服務器處理請求并返回HTTP報文:服務器根據請求參數得到返回結果,并返回HTTP報文
瀏覽器解析渲染頁面:瀏覽器得到報文,解析HTML代碼,并請求HTML代碼中的資源(例如js、css等),然后渲染頁面
連接結束:TCP4次揮手,HTTP斷開連接
知識圖譜
OSI七層架構
七層結構簡介:
7層結構數據傳輸流程:
詳細介紹每層的功能和
應用層(Application Layer)
是計算機用戶,以及各種應用程序和網絡之間的接口:
是用戶與網絡,以及應用程序與網絡間的直接接口,使得用戶能夠與網絡進行交互式聯系。
實現各種服務:該層具有的各種應用程序可以完成和實現用戶請求的各種服務。
該層還負責協調各個應用程序間的工作。
應用層為用戶提供的服務和協議有:文件服務、目錄服務、文件傳輸服務(FTP)、遠程登錄服務(Telnet)、電子郵件服務(E-mail)、打印服務、安全服務、網絡管理服務、數據庫服務等。
表示層(Presentation Layer)
對來自應用層的命令和數據進行解釋,對各種語法賦予相應的含義,并按照一定的格式傳送給會話層。
主要功能:數據格式處理、編碼、壓縮解壓、加密解密等,具體說明如下:
數據格式處理:協商和建立數據交換的格式,解決各應用程序之間在數據格式表示上的差異。
數據的編碼:處理字符集和數字的轉換。例如由于用戶程序中的數據類型(整型或實型、有符號或無符號等)、用戶標識等都可以有不同的表示方式,因此,在設備之間需要具有在不同字符集或格式之間轉換的功能。
壓縮和解壓縮:為了減少數據的傳輸量,這一層還負責數據的壓縮與恢復。
數據的加密和解密:可以提高網絡的安全性。
-
會話層(Session Layer)
其任務就是組織和協調兩個會話進程之間的通信,并對數據交換進行管理,具體如下:
會話管理:允許用戶在兩個實體設備之間建立、維持和終止會話,并支持它們之間的數據交換。例如提供單方向會話或雙向同時會話,并管理會話中的發送順序,以及會話所占用時間的長短。
會話流量控制:提供會話流量控制和交叉會話功能。
尋址:使用遠程地址建立會話連接。
出錯控制:從邏輯上講會話層主要負責數據交換的建立、保持和終止,但實際的工作卻是接收來自傳輸層的數據,并負責糾正錯誤。會話控制和遠程過程調用均屬于這一層的功能。但應注意,此層檢查的錯誤不是通信介質的錯誤,而是磁盤空間、打印機缺紙等類型的高級錯誤。
傳輸層(Transport Layer)
向用戶提供可靠的端到端的差錯和流量控制,保證報文的正確傳輸。傳輸層的作用是向高層屏蔽下層數據通信的細節,即向用戶透明地傳送報文。
傳輸連接管理:提供建立、維護和拆除傳輸連接的功能。傳輸層在網絡層的基礎上為高層提供“面向連接”和“面向無接連”的兩種服務。
處理傳輸差錯:提供可靠的“面向連接”和不太可靠的“面向無連接”的數據傳輸服務、差錯控制和流量控制。在提供“面向連接”服務時,通過這一層傳輸的數據將由目標設備確認,如果在指定的時間內未收到確認信息,數據將被重發。
監控服務質量。
該層常見的協議:TCP/IP中的TCP協議、Novell網絡中的SPX協議和微軟的NetBIOS/NetBEUI協議。
網絡層(Network Layer)
通過路由選擇算法,為報文或分組通過通信子網選擇最適當的路徑
數據鏈路層的數據在這一層被轉換為數據包,然后通過路徑選擇、分段組合、順序、進/出路由等控制,將信息從一個網絡設備傳送到另一個網絡設備。
尋址:數據鏈路層中使用的物理地址(如MAC地址)僅解決網絡內部的尋址問題。在不同子網之間通信時,為了識別和找到網絡中的設備,每一子網中的設備都會被分配一個唯一的地址。由于各子網使用的物理技術可能不同,因此這個地址應當是邏輯地址(如IP地址)。
交換:規定不同的信息交換方式。常見的交換技術有:線路交換技術和存儲轉發技術,后者又包括報文交換技術和分組交換技術。
路由算法:當源節點和目的節點之間存在多條路徑時,本層可以根據路由算法,通過網絡為數據分組選擇最佳路徑,并將信息從最合適的路徑由發送端傳送到接收端。
連接服務:與數據鏈路層流量控制不同的是,前者控制的是網絡相鄰節點間的流量,后者控制的是從源節點到目的節點間的流量。其目的在于防止阻塞,并進行差錯檢測。
數據鏈路層是解決同一網絡內節點之間的通信,而網絡層主要解決不同子網間的通信。例如在廣域網之間通信時,必然會遇到路由(即兩節點間可能有多條路徑)選擇問題。?
數據鏈路層(Data Link Layer)
物理層提供的比特流的基礎上,通過差錯控制、流量控制方法,使有差錯的物理線路變為無差錯的數據鏈路,即提供可靠的通過物理介質傳輸數據的方法。
該層通常又被分為介質訪問控制(MAC)和邏輯鏈路控制(LLC)兩個子層
MAC子層的主要任務是解決共享型網絡中多用戶對信道競爭的問題,完成網絡介質的訪問控制;
LLC子層的主要任務是建立和維護網絡連接,執行差錯校驗、流量控制和鏈路控制。數據鏈路層的具體工作是接收來自物理層的位流形式的數據,并封裝成幀,傳送到上一層;同樣,也將來自上層的數據幀,拆裝為位流形式的數據轉發到物理層;并且,還負責處理接收端發回的確認幀的信息,以便提供可靠的數據傳輸。
物理層(Physical Layer)
利用傳輸介質為數據鏈路層提供物理連接,實現比特流的透明傳輸。
物理層的作用是實現相鄰計算機節點之間比特流的透明傳送,盡可能屏蔽掉具體傳輸介質和物理設備的差異。使其上面的數據鏈路層不必考慮網絡的具體傳輸介質是什么。
分享一張大而全的七層協議框架圖
TCP/IP協議-OSI的一種“實現”
傳輸控制協議TCP簡介
面向連接的、可靠的、基于字節流的傳輸層通信協議
將應用的數據流分割成報文段并發送個給目標節點的TCP層,
分段的長度受數據鏈路層MTU(最大傳輸單元,Maximum Transmission Unit)的限制
TCP單個數據報的最大長度稱為最大段尺寸MSS;
在TCP三次握手建立連接的時候,雙方會商量傳輸中MSS的大小;
數據包都有序號以保證消息接收的順序,對方收到則發送ACK確認,未收到則重傳
使用奇偶校驗和來校驗數據在傳輸過程中是否有誤
TCP報文頭
-
SourcePort:源端口,占用2個字節。源端口和IP地址的作用是標識報文的返回地址。
p.s. IP可以唯一表示一臺主機,TCP協議和端口號可以唯一表示主機中的一個進程;所以我們可以根據IP地址+協議+端口號唯一表示網絡中的一個進程(即Socket的工作原理)。
DestinationPort:目的端口,占用2個字節;指明接收方計算機上的應用程序的端口。
SequenceNumber(序號seq):本報文段發送的數據組的第一個字節的序號。e.g.一個報文段的序號為300,此報文段數據部分共有100字節,則下一個報文段的序號為400。所以序號確保了TCP傳輸的有序性。
AcknowledgmentNumber(確認號ack):指明下一個期待收到的字節序號,表明該序號之前的所有數據已經正確無誤的收到。確認號只有當ACK標志為1時才有效。
offset(數據偏移):占用4bits。由于首部可能含有可選項內容,因此TCP報頭的長度是不確定的,報頭不包含任何任選字段則長度為20字節,4位首部長度字段所能表示的最大值為1111,轉化為10進制為15,15*32/8 = 60,故報頭最大長度為60字節。首部長度也叫數據偏移,是因為首部長度實際上指示了數據區在報文段中的起始偏移值。
Reserved(保留字節):為將來定義新的用途保留,現在一般置0。
TCP Flags(TCP控制位)
SYN:同步序號,用于建立連接過程,在連接請求中,SYN=1和ACK=0表示該數據段沒有使用捎帶的確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1。?
ACK:確認序號標志,為1時表示確認號有效,為0表示報文中不含確認信息,忽略確認號字段。?
FIN:finish標志,用于釋放連接,為1時表示發送方已經沒有數據發送了,即關閉本方數據流。
URG:緊急指針標志,為1時表示緊急指針有效,為0則忽略緊急指針。?
PSH:push標志,為1表示是帶有push標志的數據,指示接收方在接收到該報文段以后,應盡快將這個報文段交給應用程序,而不是在緩沖區排隊。?
RST:重置連接標志,用于重置由于主機崩潰或其他原因而出現錯誤的連接。或者用于拒絕非法的報文段和拒絕連接請求。?
CWR:Congestion Window Reduced
ECE:ECN echo
Window(窗口):滑動窗口大小,用來告知發送端接受端的緩存大小,以此控制發送端發送數據的速率,從而達到流量控制。窗口大小時一個16bit字段,因而窗口大小最大為65535。
Checksum(校驗和):奇偶校驗,此校驗和是對整個的?TCP?報文段,包括?TCP?頭部和?TCP?數據,以 16位進行計算所得。由發送端計算和存儲,并由接收端進行驗證。
UrgentPointer(緊急指針):只有當?URG?標志置?1?時緊急指針才有效。緊急指針是一個正的偏移量,和順序號字段中的值相加表示緊急數據最后一個字節的序號。?TCP?的緊急方式是發送端向另一端發送緊急數據的一種方式。
TCP Options(選項與填充)如果沒有選項,則TCP頭長度是20字節,TCP選項最大是40個字節。最常見的可選字段是最長報文大小,又稱為MSS(Maximum Segment Size),每個連接方通常都在通信的第一個報文段(為建立連接而設置SYN標志為1的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是32位的整數倍,所以要加填充位,即在這個字段中加入額外的零,以保證TCP頭是32的整數倍。
Data(數據部分)TCP?報文段中的數據部分是可選的。在一個連接建立和一個連接終止時,雙方交換的報文段僅有?TCP?首部。如果一方沒有數據要發送,也使用沒有任何數據的首部來確認收到的數據。在處理超時的許多情況中,也會發送不帶任何數據的報文段。
說說TCP的三次握手
在TCP/IP協議中,TCP協議提供可靠的連接服務,采用三次握手建立一個連接
第一次握手:建立連接時,客戶端發送SYN包到服務器,并進入SYN_SEND狀態,等待服務器確認。這里發送的SYN包,SYN標志位為1,seq序號初始為x
第二次握手:服務器收到SYN包,必須確認客戶的SYN,同時自己也發送一個SYN包給客戶端,此時服務端進入SYN_RECV狀態。這里服務端發送的SYN包中SYN標志位和ACK標志位都是1,seq序號初始為y,ack為x+1(表示客戶端下次再發送包seq從x+1開始)
第三次握手:客戶端收到服務器的SYN+ACK的包,向服務器發送確認包,此包ACK標志位1,seq序號為x+1,ack為y+1(表示服務端下一次發送數據seq從y+1開始)。此包發送完畢,客戶端和服務器端都進入ESTABLISHED狀態,完成三次握手,開始數據傳送。
為什么需要三次握手才能建立連接
為了初始化SequenceNumber
為了防止服務器端開啟一些無用的連接增加服務器開銷以及防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。
三次握手的隱患-SYN Flood
問題描述
Server收到Client的SYN,回復SYN-ACK的時候未收到ACK確認
Server不斷重試直至超時,Linux默認等待63秒才斷開連接(Linux默認重試5次,每次等待時間翻倍,第一次重試前等待時間為1秒,第五次重試后等待時間是32秒,然后才斷開連接)
惡意攻擊者,不斷向服務端發送SYN請求后立刻下線,服務器端會等待63秒后才斷開連接,進而導致服務端資源耗盡,讓正常的連接請求不能處理
針對SYN Flood的防護措施
針對上述問題的解決辦法
SYN隊列滿后,通過tcp_syncookies參數回發SYN Cookie
如果是正常連接,Client會回發SYN Cookie給服務端;如果是惡意攻擊,因為Client已經下線,則不會返回。
正常連接返回SYN Cookie后,可以直接建立連接
建立連接后,Client出現故障怎么辦
保活機制
向對方發送保活探測報文,如果未收到響應則繼續發送
嘗試次數達到保活探測數仍未收到響應,則中斷連接
TCP四次揮手
揮手是為了終止連接,TCP采用四次揮手來釋放連接
第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN-WAIT_1狀態;
第二次揮手:Server收到FIN后,發送一個ACK給client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態;Client接收到Server的FIN之后,進入FIN_WAIT_2狀態;
第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態;
第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次握手
為什么要有TIME_WAIT狀態
防止上一次連接中的包,迷路后重新出現,影響新連接(經過2MSL,上一次連接中所有的重復包都會消失)
可靠的關閉TCP連接。為的是確認服務器端是否收到客戶端發出的ACK確認報文。當客戶端發出最后的ACK確認報文時,并不能確定服務器端能夠收到該段報文。所以客戶端在發送完ACK確認報文之后,會設置一個時長為2MSL的計時器。MSL指的是Maximum Segment Lifetime:一段TCP報文在傳輸過程中的最大生命周期。2MSL即是服務器端發出為FIN報文和客戶端發出的ACK確認報文所能保持有效的最大時長。
服務器端在1MSL內沒有收到客戶端發出的ACK確認報文,就會再次向客戶端發出FIN報文;
如果客戶端在2MSL內,再次收到了來自服務器端的FIN報文,說明服務器端由于各種原因沒有接收到客戶端發出的ACK確認報文。客戶端再次向服務器端發出ACK確認報文,計時器重置,重新開始2MSL的計時;
否則客戶端在2MSL內沒有再次收到來自服務器端的FIN報文,說明服務器端正常接收了ACK確認報文,客戶端可以進入CLOSED階段,完成“四次揮手”。
為什么需要四次握手
因為全雙工,發送方和接收方都需要FIN報文和ACK保報文
建立連接時,被動方服務器端結束CLOSED階段進入“握手”階段并不需要任何準備,可以直接返回SYN和ACK報文,開始建立連接。釋放連接時,被動方服務器,突然收到主動方客戶端釋放連接的請求時并不能立即釋放連接,因為還有必要的數據需要處理,所以服務器先返回ACK確認收到報文,經過CLOSE-WAIT階段準備好釋放連接之后,才能返回FIN釋放連接報文。
服務器出現大量CLOSE_WAIT狀態的原因
如果一直保持在CLOSE_WAIT狀態,那么只有一種情況,就是在對方關閉連接之后服務器程序自己沒有進一步發出ack信號。換句話說,就是在對方連接關閉之后,程序里沒有檢測到,或者程序壓根就忘記了這個時候需要關閉連接,于是這個資源就一直被程序占著。
檢查代碼,特別是釋放資源的代碼
檢查配置,特別是處理請求的線程配置 ? ?
UDP報文結構
UDP 報文中每個字段的含義如下:
源端口:這個字段占據 UDP 報文頭的前 16 位,通常包含發送數據報的應用程序所使用的 UDP 端口。接收端的應用程序利用這個字段的值作為發送響應的目的地址。這個字段是可選的,所以發送端的應用程序不一定會把自己的端口號寫入該字段中。如果不寫入端口號,則把這個字段設置為 0。這樣,接收端的應用程序就不能發送響應了。
目的端口:接收端計算機上 UDP 軟件使用的端口,占據 16 位。
長度:該字段占據 16 位,表示 UDP 數據報長度,包含 UDP 報文頭和 UDP 數據長度。因為 UDP 報文頭長度是 8 個字節,所以這個值最小為 8。
校驗值:該字段占據 16 位,可以檢驗數據在傳輸過程中是否被損壞。
UDP特點
面向非連接
不維護連接狀態,支持同時向多個客戶端傳輸相同的消息
數據包報頭只有8個字節,額外開銷較小
吞吐量只受限于數據生成速率、傳輸速率以及機器性能
盡最大努力交付,不保證可靠交付,不需要維護復雜的連接狀態表
面向報文,不對應用程序提交的報文信息進行拆分或者合并
TCP和UDP的區別
可以從以下幾個方面總結區別
TCP的滑動窗口
窗口數據的計算過程
左邊是TCP發送端緩沖區,右邊是接收端緩沖區,左邊向右邊發送數據;從發送端看,下面的長條代表發送的字節流,從左向右依次發送;從接收端看,下面的長條代表接收字節流,從左向右一次接收。
LastByteAcked:指向已經接收到ack反饋的連續內存的最大位置,LastByteAcked之前字節都已經接收到接收端的ack回執
LastByteSent:指向已經發送的最后一個字節的位置
LastByteWrittten:指向上層應用已寫完的最大內存位置
LastByteRead:指向上層已經讀完的最后一個字節的位置
NextByteExpected:指向已經收到的連續內存的最大位置,已經收到了但是還沒有返回ack回執
LastByteRcvd:指向已經接收到的最大內存的位置,NextByteExpected與LastByteRcvd之間存在沒有接收到的seq
接收端可接收窗口 AdvertisedWindow 大小:
AdvertisedWindow = MaxRevBuffer - (LastByteRcvd - LastByteRead)
發送端窗口內剩余可發送的窗口 EffectiveWindow 大小:
EffectiveWindow =?AdvertisedWindow - (LastByteSent -?LastByteAcked)
這樣計算是做最壞的打算,就是認為發送端已經接收到回執的連續最大內存到已經發送的最大內存位置的數據,還在路上沒有被接收端接收;接收端的最大接收位置的都已經發送了ack,但是還沒有被上層應用處理。【這里AdvertisedWindow是接收端反饋給接收端的報文頭里window的值,告訴發送端接收端還可以接收多少數據;發送端根據window大小計算自己還可以發送多少數據】
TCP會話的發送方
TCP發送方,任何時候在其緩存內的數據都可以分為四類
Category #1:已經發送并且已經收到ack回執的部分
Category #2:已經發送但是沒有收到ack回執的部分;這部分大小是LastByteSent 與LastByteAcked的差
Category #3:已經準備好并且允許發送,但是還沒有發送的部分;這部分就是EffectiveWindow 的大小
Category #4:不允許發送的部分;已經準備好的數據,但是由于接收端緩存限制暫時不能發送的部分
其中Category #2 和 Category #3 組成了滑動窗口,當LastByteAcked向前移動的時候,滑動窗口才能向前移動。
TCP會話的接收方
TCP接收方,任何時候在其接收緩存內的數據都可以分為三類或叫三種狀態
Category #1+#2:已經接收并且已經回執ack
Category #3:未接收但是可以接收,準備接收的
Category #4:不能接收,達到了窗口的閾值了,不能接收了
因為接收到的數據TCP機制會立刻ack回執,認為沒有延遲,所以不存在已接收但沒有回執ack的狀態;
未接收但是準備接收的 Category #3 就是叫做接收窗口;接收窗口的滑動機制與發送發一致
TCP的滑動窗口總結
TCP最基本的傳輸可靠性來源于確認重傳機制,TCP的滑動窗口的可靠性也是建立在確認重傳機制的基礎上的;發送窗口只有接收到接收端對本段發送窗口內字節的ack確認,才會滑動發送窗口的左邊界;接收窗口只有在前面的端都確認的情況下,才移動左邊界,當前面字節沒有接收但是接收到后面的字節的情況下,窗口是不會移動的,并且不會對接收到的后邊的字節確認,以此讓對端確認這些字段是否需要重傳。
滑動窗口可以按照一定的策略動態的挑戰,應用程序可以根據自身的處理能力設置調整策略
HTTP簡介
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用于從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP是一個基于TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)
HTTP工作原理
HTTP協議工作于客戶端-服務端架構上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。
Web服務器有:Apache服務器,IIS服務器(Internet Information Services)等。
Web服務器根據接收到的請求后,向客戶端發送響應信息。HTTP默認端口號為80,但是你也可以改為8080或者其他端口。
HTTP三點注意事項:
HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
HTTP是媒體獨立的:這意味著,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。客戶端以及服務器指定使用適合的MIME-type內容類型。
HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
HTTP請求結構
客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成,下圖給出了請求報文的一般格式。
HTTP響應報文
實例
下面實例是一點典型的使用GET來傳遞數據的實例:
客戶端請求:
GET?/hello.txt?HTTP/1.1 User-Agent:?curl/7.16.3?libcurl/7.16.3?OpenSSL/0.9.7l?zlib/1.2.3 Host:?www.example.com? Accept-Language:?en,?mi
服務端響應:
HTTP/1.1?200?OK Date:?Mon,?27?Jul?2009?12:28:53?GMT Server:?Apache Last-Modified:?Wed,?22?Jul?2009?19:15:56?GMT ETag:?"34aa387-d-1568eb00" Accept-Ranges:?bytes Content-Length:?51 Vary:?Accept-Encoding Content-Type:?text/plain
面試題:在瀏覽器地址欄鍵入URL,按下回車之后經歷的流程
DNS解析:如果URL中是網址,需要向對這個網址進行域名解析,得到相應的IP地址,請求會逐層查詢DNS緩存得到目的IP地址(DNS緩存由近到遠依次是:瀏覽器緩存、系統緩存、路由器緩存、IPS服務器緩存、根域名服務器緩存、頂級域名服務器緩存)
TCP連接:根據IP地址和斷開,找到對應的服務器,通過TCP的三次握手建立連接
發送HTTP請求:建立TCP連接后發起HTTP請求
服務器處理請求并返回HTTP報文:服務器根據請求參數得到返回結果,并返回HTTP報文
瀏覽器解析渲染頁面:瀏覽器得到報文,解析HTML代碼,并請求HTML代碼中的資源(例如js、css等),然后渲染頁面
連接結束:TCP4次揮手,HTTP斷開連接
HTTP狀態碼
狀態碼分類
HTTP狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,后兩個數字沒有分類的作用。HTTP狀態碼共分為5種類型:
1xx:指示信息--表示請求已接收,繼續處理
2xx:請求成功-表示請求已經成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
5xx:服務器端錯誤-服務器未實現合法的請求
常見的狀態碼:
HTTP 請求方法
GET與POST請求的區別
HTTP報文層面:一般情況,GET將請求信息放在URL,POST放在請求體里面
數據層面:GET符合冪等性和安全性,POST不符合
GET請求可以被緩存,被存儲,POST不行
Cookie、Session、token
https://www.cnblogs.com/moyand/p/9047978.html
https://segmentfault.com/a/1190000017831088
Cookie
Cookie指的是瀏覽器里面能永久存儲的一種數據,僅僅是瀏覽器實現的一種數據存儲功能
cookie由服務器生成,發送給瀏覽器,瀏覽器把cookie以kv的形式保存到某個目錄的文本文件內,下一次請求同一網址時會把該cookie發送給服務端。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用,同時不會占據太多磁盤空間,所以每個域的cookie數量有限
cookie的設置和發送過程:
Session
session從字面上講,就是會話,就是服務器要知道當前發請求給自己的是誰。為了做這種區分,服務器就要給每個客戶端分配不同的“身份標識”,然后客戶端每次向服務器發送請求,都帶上這個標識,服務器就知道這個請求來源于誰。瀏覽器默認采用cookie來保存這個標識。
服務器使用session把用戶信息臨時保存在服務器上,用戶離開網站后session會被銷毀。
????注意
cookie只是實現session的其中一種方案。雖然是最常用的,但并不是唯一的方法。禁用cookie后還有其他方法存儲,比如放在url中
現在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理論上都可以保持會話狀態。可是實際中因為多種原因,一般不會單獨使用
用session只需要在客戶端保存一個id,實際上大量數據都是保存在服務端。如果全部用cookie,數據量大的時候客戶端是沒有那么多空間的。
如果只用cookie不用session,那么賬戶信息全部保存在客戶端,一旦被劫持,全部信息都會泄露。并且客戶端數據量變大,網絡傳輸的數據量也會變大
Token
token 也稱作令牌,由uid+time+sign[+固定參數]
token 的認證方式類似于臨時的證書簽名, 并且是一種服務端無狀態的認證方式, 非常適合于 REST API 的場景. 所謂無狀態就是服務端并不會保存身份認證相關的數據。
token 的認證流程與cookie很相似
用戶登錄,成功后服務器返回Token給客戶端。
客戶端收到數據后保存在客戶端
客戶端再次訪問服務器,將token放入headers中
服務器端采用filter過濾器校驗。校驗成功則返回請求數據,校驗失敗則返回錯誤碼
分布式情況下的session和token
我們已經知道session時有狀態的,一般存于服務器內存或硬盤中,當服務器采用分布式或集群時,session就會面對負載均衡問題。
負載均衡多服務器的情況,不好確認當前用戶是否登錄,因為多服務器不共享session。這個問題也可以將session存在一個服務器中來解決,但是就不能完全達到負載均衡的效果。
而token是無狀態的,token字符串里就保存了所有的用戶信息
客戶端登陸傳遞信息給服務端,服務端收到后把用戶信息加密(token)傳給客戶端,客戶端將token存放于localStroage等容器中。客戶端每次訪問都傳遞token,服務端解密token,就知道這個用戶是誰了。通過cpu加解密,服務端就不需要存儲session占用存儲空間,就很好的解決負載均衡多服務器的問題了。這個方法叫做JWT(Json Web Token)
總結
session存儲于服務器,可以理解為一個狀態列表,擁有一個唯一識別符號sessionId,通常存放于cookie中。服務器收到cookie后解析出sessionId,再去session列表中查找,才能找到相應session。依賴cookie
cookie類似一個令牌,裝有sessionId,存儲在客戶端,瀏覽器通常會自動添加。
token也類似一個令牌,無狀態,用戶信息都被加密到token中,服務器收到token后解密就可知道是哪個用戶。需要開發者手動添加。
jwt只是一個跨域認證的方案
HTTPS
https://zhuanlan.zhihu.com/p/27395037
http://www.lxweimin.com/p/14cd2c9d2cd2
HTTPS 協議(HyperText Transfer Protocol over Secure Socket Layer):可以理解為HTTP+SSL/TLS, 即 HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL,用于安全的 HTTP 數據傳輸。
如上圖所示 HTTPS 相比 HTTP 多了一層 SSL/TLS
SSL(Secure Socket Layer,安全套接字層):SSL 協議位于 TCP/IP 協議與各種應用層協議之間,為數據通訊提供安全支持。
TLS(Transport Layer Security,傳輸層安全):其前身是 SSL,目前使用最廣泛的是TLS 1.1、TLS 1.2。
SSL/TLS 為網絡通信提供安全及數據完整性的一種安全協議
SSL/TLS 是操作系統對外的API,SSL3.0后更新為TLS
SSL/TLS?采用身份驗證和數據加密保證網絡通信的安全和數據的完整性
加密算法:
對稱加密:加密和解密都是使用的同一個密鑰
有流式、分組兩種
例如:DES、AES-GCM、ChaCha20-Poly1305等
非對稱加密:加密使用的密鑰和解密使用的密鑰是不相同的
加密解密的秘鑰分別稱為:公鑰、私鑰
公鑰和算法都是公開的,私鑰是保密的。非對稱加密算法性能較低,但是安全性超強,由于其加密特性,非對稱加密算法能加密的數據長度也是有限的。
例如:RSA、DSA、ECDSA、 DH、ECDHE
哈希算法
將任意長度的信息轉換為較短的固定長度的值,通常其長度要比信息小得多,且算法不可逆。
例如:MD5、SHA-1、SHA-2、SHA-256 等
數字簽名
簽名就是在信息的后面再加上一段內容(信息經過hash后的值),可以證明信息沒有被修改過。hash值一般都會加密后(也就是簽名)再和信息一起發送,以保證這個hash值不被修改。
HTTPS數據傳輸流程
HTTPS在傳輸的過程中會涉及到三個密鑰:
服務器端的公鑰和私鑰,用來進行非對稱加密
客戶端生成的隨機密鑰,用來進行對稱加密
一個HTTPS請求實際上包含了兩次HTTP傳輸,可以細分為8步。
客戶端向服務器發起HTTPS請求,將瀏覽器支持的加密算法發送給服務器
服務器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,服務器端保存著私鑰,不能將其泄露,公鑰可以發送給任何人。
服務器選擇一套瀏覽器支持的加密算法,以證書的形式發送給客戶端,其中包含服務端的公鑰。
客戶端收到服務器端的證書之后,會對證書進行檢查,驗證其合法性,如果發現發現證書有問題,那么HTTPS傳輸就無法繼續。如果公鑰合格,那么客戶端會生成一個隨機值,這個隨機值就是用于進行對稱加密的密鑰,我們將該密鑰稱之為client key,即客戶端密鑰,這樣在概念上和服務器端的密鑰容易進行區分。然后用服務器的公鑰對客戶端密鑰進行非對稱加密,這樣客戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束。
客戶端會發起HTTPS中的第二個HTTP請求,將加密之后的客戶端密鑰發送給服務器。
服務器接收到客戶端發來的密文之后,會用自己的私鑰對其進行非對稱解密、驗證哈希,解密之后的明文就是客戶端密鑰,然后用客戶端密鑰對數據進行對稱加密,這樣數據就變成了密文。
然后服務器將加密后的密文發送給客戶端。
客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,得到服務器發送的數據。這樣HTTPS中的第二個HTTP請求結束,整個HTTPS傳輸完成。
問題:
1.怎么保證保證服務器給客戶端下發的公鑰是真正的公鑰,而不是中間人偽造的公鑰呢?
SSL 證書,權威證書機構發布CA證書
2.證書如何安全傳輸,被掉包了怎么辦?
首先,數字證書內容是加密的
包括了加密后服務器的公鑰、權威機構的信息、服務器域名,還有經過CA私鑰簽名之后的證書內容(經過先通過Hash函數計算得到證書數字摘要,然后用權威機構私鑰加密數字摘要得到數字簽名),簽名計算方法以及證書對應的域名。
驗證證書過程是安全的
當客戶端收到這個證書之后,使用本地配置的權威機構的公鑰對證書進行解密得到服務端的公鑰和證書的數字簽名,數字簽名經過CA公鑰解密得到證書信息摘要。
然后證書簽名的方法計算一下當前證書的信息摘要,與收到的信息摘要作對比,如果一樣,表示證書一定是服務器下發的,沒有被中間人篡改過。因為中間人雖然有權威機構的公鑰,能夠解析證書內容并篡改,但是篡改完成之后中間人需要將證書重新加密,但是中間人沒有權威機構的私鑰,無法加密,強行加密只會導致客戶端無法解密,如果中間人強行亂修改證書,就會導致證書內容和證書簽名不匹配。
HTTPS和HTTP的區別
HTTPS需要到CA申請證書,HTTP不需要
HTTPS密文傳輸,HTTP明文傳輸
連接方式不同,HTTPS默認使用443端口,HTTP默認80
HTTPS=HTTP+加密+認證+完整性保護,較HTTP安全
Socket簡介
socket是對TCP/IP協議的抽象,是操作系統對外開放的接口
Socket通信流程
客戶端:
4.用戶創建socket
5.用戶打開socket,并通過IP地址+端口號試圖connect服務器的socket
7.客戶端連接成功,開始向服務器輸入狀態信息
9.客戶端寫入信息
11.客戶端關閉
服務器:
1.服務器根據地址類型(ipv4、ipv6)、socket類型、協議創建socket
2.服務器為socket綁定對應的IP地址和端口號
3.服務器監聽端口號請求,接收用戶發來的連接請求,此時服務器沒有打開socket
6.服務器接收到了用戶發來的socket連接請求,被動打開socket,開始接收客戶端請求,直到用戶返回連接信息。這時候服務器的socket進入堵塞狀態,所謂堵塞,即accept();方法一直接收到客戶端返回連接信息后才返回,然后開始接收下一個用戶端請求
8.服務器accept();方法返回,連接成功
10.服務器讀取信息
12.服務端關閉
完成~
小猿同事面試過程中,計算機網絡相關的基礎知識也就問了這么多,肯定還是有很多知識點和細節沒有介紹到,小猿和同事們還需要繼續努力深究,爭取再整理更詳細的知識點分析給大家~