計算機網絡
什么是三次握手 (three-way handshake)?
- 第一次握手:Client將SYN置1,隨機產生一個初始序列號seq發送給Server,進入SYN_SENT狀態;
- 第二次握手:Server收到Client的SYN=1之后,知道客戶端請求建立連接,將自己的SYN置1,ACK置1,產生一個acknowledge number=sequence number+1,並隨機產生一個自己的初始序列號,發送給客戶端;進入SYN_RCVD狀態;
- 第三次握手:客戶端檢查acknowledge number是否為序列號+1,ACK是否為1,檢查正確之后將自己的ACK置為1,產生一個acknowledge number=服務器發的序列號+1,發送給服務器;進入ESTABLISHED狀態;服務器檢查ACK為1和acknowledge number為序列號+1之后,也進入ESTABLISHED狀態;完成三次握手,連接建立。
TCP建立連接可以兩次握手嗎?為什么?
展開不可以。有兩個原因:
首先,可能會出現已失效的連接請求報文段又傳到了服務器端。
client 發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達 server。本來這是一個早已失效的報文段。但 server 收到此失效的連接請求報文段后,就誤認為是 client 再次發出的一個新的連接請求。於是就向 client 發出確認報文段,同意建立連接。假設不采用 “三次握手”,那么只要 server 發出確認,新的連接就建立了。由於現在 client 並沒有發出建立連接的請求,因此不會理睬 server 的確認,也不會向 server 發送數據。但 server 卻以為新的運輸連接已經建立,並一直等待 client 發來數據。這樣,server 的很多資源就白白浪費掉了。采用 “三次握手” 的辦法可以防止上述現象發生。例如剛才那種情況,client 不會向 server 的確認發出確認。server 由於收不到確認,就知道 client 並沒有要求建立連接。
其次,兩次握手無法保證Client正確接收第二次握手的報文(Server無法確認Client是否收到),也無法保證Client和Server之間成功互換初始序列號。
可以采用四次握手嗎?為什么?
展開可以。但是會降低傳輸的效率。
四次握手是指:第二次握手:Server只發送ACK和acknowledge number;而Server的SYN和初始序列號在第三次握手時發送;原來協議中的第三次握手變為第四次握手。出於優化目的,四次握手中的二、三可以合並。
第三次握手中,如果客戶端的ACK未送達服務器,會怎樣?
展開Server端:
由於Server沒有收到ACK確認,因此會重發之前的SYN+ACK(默認重發五次,之后自動關閉連接進入CLOSED狀態),Client收到后會重新傳ACK給Server。
Client端,兩種情況:
- 在Server進行超時重發的過程中,如果Client向服務器發送數據,數據頭部的ACK是為1的,所以服務器收到數據之后會讀取 ACK number,進入 establish 狀態
- 在Server進入CLOSED狀態之后,如果Client向服務器發送數據,服務器會以RST包應答。
如果已經建立了連接,但客戶端出現了故障怎么辦?
展開服務器每收到一次客戶端的請求后都會重新復位一個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以后每隔75秒鍾發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接着就關閉連接。
初始序列號是什么?
展開TCP連接的一方A,隨機選擇一個32位的序列號(Sequence Number)作為發送數據的初始序列號(Initial Sequence Number,ISN),比如為1000,以該序列號為原點,對要傳送的數據進行編號:1001、1002...三次握手時,把這個初始序列號傳送給另一方B,以便在傳輸數據時,B可以確認什么樣的數據編號是合法的;同時在進行數據傳輸時,A還可以確認B收到的每一個字節,如果A收到了B的確認編號(acknowledge number)是2001,就說明編號為1001-2000的數據已經被B成功接受。
什么是四次揮手?
- 第一次揮手:Client將FIN置為1,發送一個序列號seq給Server;進入FIN_WAIT_1狀態;
- 第二次揮手:Server收到FIN之后,發送一個ACK=1,acknowledge number=收到的序列號+1;進入CLOSE_WAIT狀態。此時客戶端已經沒有要發送的數據了,但仍可以接受服務器發來的數據。
- 第三次揮手:Server將FIN置1,發送一個序列號給Client;進入LAST_ACK狀態;
- 第四次揮手:Client收到服務器的FIN后,進入TIME_WAIT狀態;接着將ACK置1,發送一個acknowledge number=序列號+1給服務器;服務器收到后,確認acknowledge number后,變為CLOSED狀態,不再向客戶端發送數據。客戶端等待2*MSL(報文段最長壽命)時間后,也進入CLOSED狀態。完成四次揮手。
為什么不能把服務器發送的ACK和FIN合並起來,變成三次揮手(CLOSE_WAIT狀態意義是什么)?
展開因為服務器收到客戶端斷開連接的請求時,可能還有一些數據沒有發完,這時先回復ACK,表示接收到了斷開連接的請求。等到數據發完之后再發FIN,斷開服務器到客戶端的數據傳送。
如果第二次揮手時服務器的ACK沒有送達客戶端,會怎樣?
展開客戶端沒有收到ACK確認,會重新發送FIN請求。
客戶端TIME_WAIT狀態的意義是什么?
展開第四次揮手時,客戶端發送給服務器的ACK有可能丟失,TIME_WAIT狀態就是用來重發可能丟失的ACK報文。如果Server沒有收到ACK,就會重發FIN,如果Client在2*MSL的時間內收到了FIN,就會重新發送ACK並再次等待2MSL,防止Server沒有收到ACK而不斷重發FIN。
MSL(Maximum Segment Lifetime),指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回復所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那么Client推斷ACK已經被成功接收,則結束TCP連接。
TCP如何實現流量控制?
使用滑動窗口協議實現流量控制。防止發送方發送速率太快,接收方緩存區不夠導致溢出。接收方會維護一個接收窗口 receiver window(窗口大小單位是字節),接受窗口的大小是根據自己的資源情況動態調整的,在返回ACK時將接受窗口大小放在TCP報文中的窗口字段告知發送方。發送窗口的大小不能超過接受窗口的大小,只有當發送方發送並收到確認之后,才能將發送窗口右移。
發送窗口的上限為接受窗口和擁塞窗口中的較小值。接受窗口表明了接收方的接收能力,擁塞窗口表明了網絡的傳送能力。
什么是零窗口(接收窗口為0時會怎樣)?
展開如果接收方沒有能力接收數據,就會將接收窗口設置為0,這時發送方必須暫停發送數據,但是會啟動一個持續計時器(persistence timer),到期后發送一個大小為1字節的探測數據包,以查看接收窗口狀態。如果接收方能夠接收數據,就會在返回的報文中更新接收窗口大小,恢復數據傳送。
TCP的擁塞控制是怎么實現的?
擁塞控制主要由四個算法組成:慢啟動(Slow Start)、擁塞避免(Congestion voidance)、快重傳 (Fast Retransmit)、快恢復(Fast Recovery)
- 慢啟動:剛開始發送數據時,先把擁塞窗口(congestion window)設置為一個最大報文段MSS的數值,每收到一個新的確認報文之后,就把擁塞窗口加1個MSS。這樣每經過一個傳輸輪次(或者說是每經過一個往返時間RTT),擁塞窗口的大小就會加倍
- 擁塞避免:當擁塞窗口的大小達到慢開始門限(slow start threshold)時,開始執行擁塞避免算法,擁塞窗口大小不再指數增加,而是線性增加,即每經過一個傳輸輪次只增加1MSS.
無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認),就要把慢開始門限ssthresh設置為出現擁塞時的發送方窗口值的一半(但不能小於2)。然后把擁塞窗口cwnd重新設置為1,執行慢開始算法。(這是不使用快重傳的情況)
- 快重傳:快重傳要求接收方在收到一個失序的報文段后就立即發出重復確認(為的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時捎帶確認。快重傳算法規定,發送方只要一連收到三個重復確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器時間到期。
- 快恢復:當發送方連續收到三個重復確認時,就把慢開始門限減半,然后執行擁塞避免算法。不執行慢開始算法的原因:因為如果網絡出現擁塞的話就不會收到好幾個重復的確認,所以發送方認為現在網絡可能沒有出現擁塞。
也有的快重傳是把開始時的擁塞窗口cwnd值再增大一點,即等於 ssthresh + 3*MSS 。這樣做的理由是:既然發送方收到三個重復的確認,就表明有三個分組已經離開了網絡。這三個分組不再消耗網絡的資源而是停留在接收方的緩存中。可見現在網絡中減少了三個分組。因此可以適當把擁塞窗口擴大些。
TCP如何最大利用帶寬?
TCP速率受到三個因素影響
- 窗口:即滑動窗口大小,見TCP如何實現流量控制?
- 帶寬:這里帶寬是指單位時間內從發送端到接收端所能通過的“最高數據率”,是一種硬件限制。TCP發送端和接收端的數據傳輸數不可能超過兩點間的帶寬限制。發送端和接收端之間帶寬取所通過線路的帶寬最小值(如通過互聯網連接)。
- RTT:即Round Trip Time,表示從發送端到接收端的一去一回需要的時間,TCP在數據傳輸過程中會對RTT進行采樣(即對發送的數據包及其ACK的時間差進行測量,並根據測量值更新RTT值),TCP根據得到的RTT值更新RTO值,即Retransmission TimeOut,就是重傳間隔,發送端對每個發出的數據包進行計時,如果在RTO時間內沒有收到所發出的數據包的對應ACK,則任務數據包丟失,將重傳數據。一般RTO值都比采樣得到的RTT值要大。
帶寬時延乘積=帶寬*RTT,實際上等於發送端到接收端單向通道的數據容積的兩倍,這里單向通道的數據容積可以這樣來理解,單向通道看成是一條單行道馬路,帶寬就是馬路的車道數,路上跑的汽車就是數據(不過這里所有汽車的速率都是一樣的,且不會有人想超車,大家齊頭並進),那么單向通道的數據容積就是這條單行道上擺滿車,一共可以擺多少輛。帶寬就是馬路的車道數,帶寬數乘以單向通道的數據容積就是路面上所能容納的全部數據量。當路面上已經擺滿的時候,就不能再往里面放了。
前面已經說過了,TCP發送數據時受滑動窗口的限制,當TCP將滑動窗口中的數據都發出后,在收到第一個ACK之前,滑動窗口大小是0,不能再發送數據了,必須等待ACK包使滑動窗口移動。那么在理想情況下,ACK包應該在什么時候到達呢?顯然,就是在數據發出后的RTT時間后,ACK包到達。這也就是說,現在在不考慮丟包和擁塞情況下,TCP在一個RTT時間內能發出的最大數據量為 ,所以不考慮帶寬限制下,TCP能一個時刻能達到的最大速度是
。
現在再考慮帶寬限制,前面說過當馬路上擺滿車的時候,就無法再往里放車了,同理,TCP發送端在 時間內,能往通道上放的最大數據量為
,通過帶寬時延乘積得到的容積限制為
。當
時,單向通道容積不構成瓶頸,速率的限制主要來源於窗口大小限制。而當
時,則就受到容積限制,即此時速率限制來源於帶寬限制。
在我們平時生活中使用的寬帶網絡,ADSL等環境下,因為帶寬都比較小,從而 也比較小,再加上網絡情況比較復雜,擁塞情況比較常見,所以這些網絡環境下,TCP速率的主要限制因素在於帶寬,丟包率等。長肥管道一般不太常見,多見於一些單位使用的專線網絡,在這些網絡中速率的主要限制因素就是窗口大小了,這也是傳統TCP在這些網絡環境中不能充分利用帶寬的原因所在(因為傳統TCP的窗口大小是用2字節表示的,所以最大只有65535(不考慮窗口擴大選項)),除了專線網絡外,隨着網絡硬件技術的發展,萬兆交換機的出現,局域網中也可能會出現帶寬時延乘積較大的情況。
TCP與UDP的區別
- TCP是面向連接的,UDP是無連接的;
UDP發送數據之前不需要建立連接
- TCP是可靠的,UDP不可靠;
UDP接收方收到報文后,不需要給出任何確認
- TCP只支持點對點通信,UDP支持一對一、一對多、多對一、多對多;
- TCP是面向字節流的,UDP是面向報文的;
面向字節流是指發送數據時以字節為單位,一個數據包可以拆分成若干組進行發送,而UDP一個報文只能一次發完。
- TCP有擁塞控制機制,UDP沒有。網絡出現的擁塞不會使源主機的發送速率降低,這對某些實時應用是很重要的,比如媒體通信,游戲;
- TCP首部開銷(20字節)比UDP首部開銷(8字節)要大
- UDP 的主機不需要維持復雜的連接狀態表
什么時候選擇TCP,什么時候選UDP?
展開 對某些實時性要求比較高的情況,選擇UDP,比如游戲,媒體通信,實時視頻流(直播),即使出現傳輸錯誤也可以容忍;其它大部分情況下,HTTP都是用TCP,因為要求傳輸的內容可靠,不出現丟失HTTP可以使用UDP嗎?
展開 HTTP不可以使用UDP,HTTP需要基於可靠的傳輸協議,而UDP不可靠注:http 3.0 使用udp實現 https://zh.wikipedia.org/wiki/HTTP/3
面向連接和無連接的區別
展開無連接的網絡服務(數據報服務)-- 面向連接的網絡服務(虛電路服務)
虛電路服務:首先建立連接,所有的數據包經過相同的路徑,服務質量有較好的保證;
數據報服務:每個數據包含目的地址,數據路由相互獨立(路徑可能變化);網絡盡最大努力交付數據,但不保證不丟失、不保證先后順序、不保證在時限內交付;網絡發生擁塞時,可能會將一些分組丟棄;
TCP如何保證傳輸的可靠性
- 數據包校驗
- 對失序數據包重新排序(TCP報文具有序列號)
- 丟棄重復數據
- 應答機制:接收方收到數據之后,會發送一個確認(通常延遲幾分之一秒);
- 超時重發:發送方發出數據之后,啟動一個定時器,超時未收到接收方的確認,則重新發送這個數據;
- 流量控制:確保接收端能夠接收發送方的數據而不會緩沖區溢出
HTTP和HTTPS有什么區別?
- 端口不同:HTTP使用的是80端口,HTTPS使用443端口;
- HTTP(超文本傳輸協議)信息是明文傳輸,HTTPS運行在SSL(Secure Socket Layer)之上,添加了加密和認證機制,更加安全;
- HTTPS由於加密解密會帶來更大的CPU和內存開銷;
- HTTPS通信需要證書,一般需要向證書頒發機構(CA)購買
Https的連接過程?
展開- 客戶端向服務器發送請求,同時發送客戶端支持的一套加密規則(包括對稱加密、非對稱加密、摘要算法);
- 服務器從中選出一組加密算法與HASH算法,並將自己的身份信息以證書的形式發回給瀏覽器。證書里面包含了網站地址,加密公鑰(用於非對稱加密),以及證書的頒發機構等信息(證書中的私鑰只能用於服務器端進行解密);
- 客戶端驗證服務器的合法性,包括:證書是否過期,CA 是否可靠,發行者證書的公鑰能否正確解開服務器證書的“發行者的數字簽名”,服務器證書上的域名是否和服務器的實際域名相匹配;
- 如果證書受信任,或者用戶接收了不受信任的證書,瀏覽器會生成一個隨機密鑰(用於對稱算法),並用服務器提供的公鑰加密(采用非對稱算法對密鑰加密);使用Hash算法對握手消息進行摘要計算,並對摘要使用之前產生的密鑰加密(對稱算法);將加密后的隨機密鑰和摘要一起發送給服務器;
- 服務器使用自己的私鑰解密,得到對稱加密的密鑰,用這個密鑰解密出Hash摘要值,並驗證握手消息是否一致;如果一致,服務器使用對稱加密的密鑰加密握手消息發給瀏覽器;
- 瀏覽器解密並驗證摘要,若一致,則握手結束。之后的數據傳送都使用對稱加密的密鑰進行加密
總結:非對稱加密算法用於在握手過程中加密生成的密碼;對稱加密算法用於對真正傳輸的數據進行加密;HASH算法用於驗證數據的完整性。
輸入 www.baidu.com,怎么變成 https://www.baidu.com 的,怎么確定用HTTP還是HTTPS?
展開一種是原始的302跳轉,服務器把所有的HTTp流量跳轉到HTTPS。但這樣有一個漏洞,就是中間人可能在第一次訪問站點的時候就劫持。 解決方法是引入HSTS機制,用戶瀏覽器在訪問站點的時候強制使用HTTPS。
HTTPS連接的時候,怎么確定收到的包是服務器發來的(中間人攻擊)?
展開什么是對稱加密、非對稱加密?區別是什么?
展開- 對稱加密:加密和解密采用相同的密鑰。如:DES、RC2、RC4
- 非對稱加密:需要兩個密鑰:公鑰和私鑰。如果用公鑰加密,需要用私鑰才能解密。如:RSA
- 區別:對稱加密速度更快,通常用於大量數據的加密;非對稱加密安全性更高(不需要傳送私鑰)
數字簽名、報文摘要的原理
展開- 發送者A用私鑰進行簽名,接收者B用公鑰驗證簽名。因為除A外沒有人有私鑰,所以B相信簽名是來自A。A不可抵賴,B也不能偽造報文。
- 摘要算法:MD5、SHA
GET與POST的區別?
- GET是冪等的,即讀取同一個資源,總是得到相同的數據,POST不是冪等的;
- GET一般用於從服務器獲取資源,而POST有可能改變服務器上的資源;
- 請求形式上:GET請求的數據附在URL之后,在HTTP請求頭中;POST請求的數據在請求體中;
- 安全性:GET請求可被緩存、收藏、保留到歷史記錄,且其請求數據明文出現在URL中。POST的參數不會被保存,安全性相對較高;
- GET只允許ASCII字符,POST對數據類型沒有要求,也允許二進制數據;
- GET的長度有限制(操作系統或者瀏覽器),而POST數據大小無限制
Session與Cookie的區別?
Session是服務器端保持狀態的方案,Cookie是客戶端保持狀態的方案
Cookie保存在客戶端本地,客戶端請求服務器時會將Cookie一起提交;Session保存在服務端,通過檢索Sessionid查看狀態。保存Sessionid的方式可以采用Cookie,如果禁用了Cookie,可以使用URL重寫機制(把會話ID保存在URL中)。
從輸入網址到獲得頁面的過程 (越詳細越好)?
- 瀏覽器查詢 DNS,獲取域名對應的IP地址:具體過程包括瀏覽器搜索自身的DNS緩存、搜索操作系統的DNS緩存、讀取本地的Host文件和向本地DNS服務器進行查詢等。對於向本地DNS服務器進行查詢,如果要查詢的域名包含在本地配置區域資源中,則返回解析結果給客戶機,完成域名解析(此解析具有權威性);如果要查詢的域名不由本地DNS服務器區域解析,但該服務器已緩存了此網址映射關系,則調用這個IP地址映射,完成域名解析(此解析不具有權威性)。如果本地域名服務器並未緩存該網址映射關系,那么將根據其設置發起遞歸查詢或者迭代查詢;
- 瀏覽器獲得域名對應的IP地址以后,瀏覽器向服務器請求建立鏈接,發起三次握手;
- TCP/IP鏈接建立起來后,瀏覽器向服務器發送HTTP請求;
- 服務器接收到這個請求,並根據路徑參數映射到特定的請求處理器進行處理,並將處理結果及相應的視圖返回給瀏覽器;
- 瀏覽器解析並渲染視圖,若遇到對js文件、css文件及圖片等靜態資源的引用,則重復上述步驟並向服務器請求這些資源;
- 瀏覽器根據其請求到的資源、數據渲染頁面,最終向用戶呈現一個完整的頁面。
HTTP請求有哪些常見狀態碼?
- 2xx狀態碼:操作成功。200 OK
- 3xx狀態碼:重定向。301 永久重定向;302暫時重定向
- 4xx狀態碼:客戶端錯誤。400 Bad Request;401 Unauthorized;403 Forbidden;404 Not Found;
- 5xx狀態碼:服務端錯誤。500服務器內部錯誤;501服務不可用
什么是RIP (Routing Information Protocol, 距離矢量路由協議)? 算法是什么?
每個路由器維護一張表,記錄該路由器到其它網絡的”跳數“,路由器到與其直接連接的網絡的跳數是1,每多經過一個路由器跳數就加1;更新該表時和相鄰路由器交換路由信息;路由器允許一個路徑最多包含15個路由器,如果跳數為16,則不可達。交付數據報時優先選取距離最短的路徑。
(PS:RIP是應用層協議:https://www.zhihu.com/question/19645407)
優缺點- 實現簡單,開銷小
- 隨着網絡規模擴大開銷也會增大;
- 最大距離為15,限制了網絡的規模;
- 當網絡出現故障時,要經過較長的時間才能將此信息傳遞到所有路由器
計算機網絡體系結構
- Physical, Data Link, Network, Transport, Application
- 應用層:常見協議:
- FTP(21端口):文件傳輸協議
- SSH(22端口):遠程登陸
- TELNET(23端口):遠程登錄
- SMTP(25端口):發送郵件
- POP3(110端口):接收郵件
- HTTP(80端口):超文本傳輸協議
- DNS(53端口):運行在UDP上,域名解析服務
- 傳輸層:TCP/UDP
- 網絡層:IP、ARP、NAT、RIP...
- 路由器網絡層,根據IP地址進行尋址;
- 交換機數據鏈路層,根據MAC地址進行尋址
IP地址的分類?
路由器僅根據網絡號net-id來轉發分組,當分組到達目的網絡的路由器之后,再按照主機號host-id將分組交付給主機;同一網絡上的所有主機的網絡號相同。
什么叫划分子網?
從主機號host-id借用若干個比特作為子網號subnet-id;子網掩碼:網絡號和子網號都為1,主機號為0;數據報仍然先按照網絡號找到目的網絡,發送到路由器,路由器再按照網絡號和子網號找到目的子網:將子網掩碼與目標地址逐比特與操作,若結果為某個子網的網絡地址,則送到該子網。
什么是ARP協議 (Address Resolution Protocol)?
ARP協議完成了IP地址與物理地址的映射。每一個主機都設有一個 ARP 高速緩存,里面有所在的局域網上的各主機和路由器的 IP 地址到硬件地址的映射表。當源主機要發送數據包到目的主機時,會先檢查自己的ARP高速緩存中有沒有目的主機的MAC地址,如果有,就直接將數據包發到這個MAC地址,如果沒有,就向所在的局域網發起一個ARP請求的廣播包(在發送自己的 ARP 請求時,同時會帶上自己的 IP 地址到硬件地址的映射),收到請求的主機檢查自己的IP地址和目的主機的IP地址是否一致,如果一致,則先保存源主機的映射到自己的ARP緩存,然后給源主機發送一個ARP響應數據包。源主機收到響應數據包之后,先添加目的主機的IP地址與MAC地址的映射,再進行數據傳送。如果源主機一直沒有收到響應,表示ARP查詢失敗。
如果所要找的主機和源主機不在同一個局域網上,那么就要通過 ARP 找到一個位於本局域網上的某個路由器的硬件地址,然后把分組發送給這個路由器,讓這個路由器把分組轉發給下一個網絡。剩下的工作就由下一個網絡來做。
什么是NAT (Network Address Translation, 網絡地址轉換)?
用於解決內網中的主機要和因特網上的主機通信。由NAT路由器將主機的本地IP地址轉換為全球IP地址,分為靜態轉換(轉換得到的全球IP地址固定不變)和動態NAT轉換。