面試過程中經常會被問到計算機網絡相關的知識,就打算寫一篇博客不斷總結一些計算機網絡的基礎點以及面試中常問的考點。如果文檔中存在錯誤歡迎指出,有任何補充留言私信均可以,我會不定期的添加上去。話不多說,直接進入主題:
目錄
4.2爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
4.4 如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?
1.OSI網絡體系結構和TCP/IP協議結構
從下到上分爲:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層
網絡接口層對應於OSI的物理層和數據鏈路層,應用層對應於OSI的會話層、表示層、應用層。
2.HTTP和HTTPS協議
Http協議運行在TCP之上,明文傳輸,客戶端與服務器端都無法驗證對方的身份;Https是身披SSL(Secure Socket Layer)外殼的Http,運行於SSL上,SSL運行於TCP之上,是添加了加密和認證機制的HTTP。二者之間存在如下不同:
端口不同:Http與Http使用不同的連接方式,用的端口也不一樣,前者是80,後者是443;
資源消耗:和HTTP通信相比,Https通信會由於加減密處理消耗更多的CPU和內存資源;
開銷:Https通信需要證書,而證書一般需要向認證機構購買;
Https的加密機制是一種共享密鑰加密和公開密鑰加密並用的混合加密機制。
GET /user HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
<html>...
第一部分:請求行:請求類型,資源路徑以及http版本(上述第一行)
第二部分:請求頭:緊接在請求行之後,用於說明服務器需要使用的附加信息(第二到第八行)
HTTP/1.1 200
Content-Type:text/html
OK
第二部分:響應報文頭部,說明服務器需要用到的附加信息(第二行)
3.TCP協議和UDP協議
TCP是傳輸層協議,TCP提供了數據的可靠連接,通過面向連接、端到端和可靠的字節流服務。
UDP是傳輸層協議,UDP在數據傳輸前不會建立連接,不能保證數據連接的可靠性,傳輸速度快。
4.TCP協議的三次握手和四次揮手
第一次握手:建立連接時,客戶端發送syn包(seq=x)到服務器,並進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=x+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。
第一次揮手:客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號爲seq=u(等於前面已經傳送過來的數據的最後一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
第二次揮手:服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)。
第三次揮手:服務器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號爲seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
第四次揮手:客戶端收到服務器的連接釋放報文後,必鬚髮出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2∗∗MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
4.1 爲什麼連接的時候是三次握手,關閉的時候卻是4次揮手
因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。
4.2爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可能最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最後的ACK回覆,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重複發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之後進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連接。
4.3爲什麼要用三次握手而不是兩次或四次
3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。
現在把三次握手改成僅需要兩次握手,當第二次握手後(即服務器發送給客戶端)的請求客戶端沒收到時,服務器會認爲已經建立了連接,開始發送數據,但是客戶端沒收到連接請求,會認爲連接未建立,繼續發送連接信息。這時就導致了死鎖。
至於爲什麼不改成四次,當三次連接後,服務器和客戶機都能確定之前的通信情況,但是無法確認之後的情況,可靠的通信協議是根本不存在的,因此再增加一次也是徒勞。
4.4 如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?
TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。
5.常見的網絡協議有哪些?
6.常見的網絡攻擊方式?以及預防措施
6.1 DDoS
DDoS全稱Distributed Denial of Service,中文意思爲“分佈式拒絕服務”,就是利用大量合法的分佈式服務器對目標發送請求,從而導致正常合法用戶無法獲得服務。
客戶端不向服務端發送確認數據包,服務器一直等待來自客戶端的確認
6.2 SQL注入
攻擊者不是將標準數據提交到文本框或其他數據輸入字段,而是輸入SQL語句來誘騙應用程序顯示或操縱其數據。
對訪問數據庫的Web應用程序使用Web應用程序防火牆(WAF)
6.3 XSS攻擊
XSS 攻擊,即跨站腳本攻擊(Cross Site Scripting),它是 web 程序中常見的漏洞。 攻擊者破壞易受攻擊的網站或Web應用程序並注入惡意代碼。當頁面加載時,代碼在用戶的瀏覽器上執行惡意腳本。
web 頁面用戶輸入的地方,對輸入的數據轉義、過濾處理。後臺輸出頁面的時候,也需要對輸出內容進行轉義、過濾處理(因爲攻擊者可能通過其他方式把惡意腳本寫入數據庫)
6.4 CSRF攻擊
跨站請求僞造(英語:Cross-site request forgery),是一種挾制用戶在當前已登錄的Web應用程序上執行非本意的操作的攻擊方法。
HTTP頭中有一個Referer字段,這個字段用以標明請求來源於哪個地址。在處理敏感數據請求時,通常來說,Referer字段應和請求的地址位於同一域名下。以上文銀行操作爲例,Referer字段地址通常應該是轉賬按鈕所在的網頁地址,應該也位於www.examplebank.com之下。而如果是CSRF攻擊傳來的請求,Referer字段會是包含惡意網址的地址,不會位於www.examplebank.com之下,這時候服務器就能識別出惡意的訪問。
由於CSRF的本質在於攻擊者欺騙用戶去訪問自己設置的地址,所以如果要求在訪問敏感數據請求時,要求用戶瀏覽器提供不保存在cookie中,並且攻擊者無法僞造的數據作爲校驗,那麼攻擊者就無法再運行CSRF攻擊。這種數據通常是窗體中的一個數據項。服務器將其生成並附加在窗體中,其內容是一個僞隨機數。當客戶端通過窗體提交請求時,這個僞隨機數也一併提交上去以供校驗。正常的訪問時,客戶端瀏覽器能夠正確得到並傳回這個僞隨機數,而通過CSRF傳來的欺騙性攻擊中,攻擊者無從事先得知這個僞隨機數的值,服務端就會因爲校驗token的值爲空或者錯誤,拒絕這個可疑請求。
7.TCP協議的粘包問題
TCP 是面向連接的,面向流的可靠協議;發送端爲了將多個發往接收端的包,更有效的發到對方,使用了優化方法(Nagle算法),將多次間隔較小且數據量小的數據,合併成一個大的數據塊,然後進行封包。這樣,接收端,就難於分辨出來了,就會出現所謂的粘包問題。
(1)發送端需要等緩衝區滿才發送出去,造成粘包(發送數據時間間隔很短,數據了很小,會合到一起,產生粘包)
(2)接收方不及時接收緩衝區的包,造成多個包接收(客戶端發送了一段數據,服務端只收了一小部分,服務端下次再收的時候還是從緩衝區拿上次遺留的數據,產生粘包)
在進行數據發送的時候採用固定長度的設計,無論多大的數據包都分成固定的長度進行發送,這種方式的弊端在於,最後一個包的長度往往會被填充爲空格,接收方可能無法辨別無效部分。
在一個包結束的位置增加一個特殊的標記,當接收方讀取到這個標記後就說明數據包讀取完畢,這種方式的弊端在於取什麼樣的數據作爲標誌位是一件很難找到恰當答案的事情。