android tcp 面試

參考:https://www.cnblogs.com/wulala1119/p/4749892.html

tpc/ip 的四層模型

  • 網絡接入層:將需要相互連接的節點接入網絡中,從而爲數據傳輸提供條件。
  • 網絡互聯層:找到要傳輸數據的目標節點。(IP協議)
  • 傳輸層:實際傳輸數據。(TCP 、UDP協議)
  • 應用層:使用接收到的數據。(HTTP、HTTPS、DNS協議)

tcp/ip 協議

是兩個不同的協議,所起的作用也不一樣。IP協議是用來查找地址的,對應着網際互聯層,TCP協議是用來規範傳輸規則的,對應着傳輸層。IP只負責找到地址,具體傳輸工作交給TCP來完成。

TCP在傳輸之前會進行三次溝通,一般稱爲“三次握手”,傳完數據斷開的時候,要進行四次溝通,一般稱爲“四次揮手”。要理解這個過程首先需要理解TCP中的兩個序號和三個標誌位的含義:

  • seq:sequence number的縮寫,表示所傳數據的序號。TCP傳輸時每一個字節都有一個序號,發送數據時會將數據的第一個序號發送給對方,接收方會按序號檢查是否接收完整了,如果沒有接收完整就需要重新傳送,這樣就可以保證數據的完整性。
  • ack:asknoledgement number的縮寫,表示確認號。接收端用它來給發送端反饋已經成功接收到的數據信息,它的值爲希望接收的下一個數據包起始序號,也就是ack值所代表的序號前面數據已經成功接收到了。
  • ACK:確認位,只有ACK=1的時候ack才起作用。正常通信時ACK爲1,第一次發起請求時因爲沒有需要確認接收的數據所以ACK爲0。
  • SYN:同步位,用於在建立連接時同時序號。剛開始建立連接時並沒有歷史接收數據,所以ack也就沒辦法設置,這時按照正常的就無法運行了,SYN的作用就是來解決這個問題的,當接收端接收到SYN=1的報文時就會直接將ack設置爲接收到的seq+1的值,注意這裏面的值並不是校驗後設置的,而是根據SYN直接設置的,這樣正常的機制就可以運行了,所以SYN叫同步位。需要注意的是,SYN會在前面再次握手時都爲1,這是因爲通信的雙方的ack都需要設置一個初始值。
  • FIN:終止位,用來在數據傳輸完畢後釋放連接。

面試題

發送序號和確認序號問題

  • 例: TCP建立連接的過程採用三次握手,已知第三次握手報文的發送序列號爲1000,確認序列號爲2000,請問第二次握手報文的發送序列號和確認序列號分別爲?
  • 答:看答案時請參考上面TCP連接建立的圖。
  • 客戶端:發送X
  • 服務端:發送Y, 確認X+1
  • 客戶端:發送X+1(1000),確認Y+1(2000)
  • 可以反推第二次爲1999,確認1000

SYN Flood 攻擊原理及防禦

SYN Flood是當前最流行的DoS(拒絕服務攻擊)與DDoS(分佈式拒絕服務攻擊)的方式之一,這是一種利用TCP協議缺陷,發送大量僞造的TCP連接請求,從而使得被攻擊方資源耗盡(CPU滿負荷或內存不足)的攻擊方式。

原理
問題出在TCP連接的三次握手中,惡意的攻擊者大量發送SYN報文,服務器端將爲了維護一個非常大的半連接列表而消耗非常多的資源----數以萬計的半連接,即使是簡單的保存並遍歷也會消耗非常多的CPU時間和內存,何況還要不斷對這個列表中的IP進行SYN+ACK的重試。實際上如果服務器的TCP/IP棧不夠強大,最後的結果往往是堆棧溢出崩潰—即使服務器端的系統足夠強大,服務器端也將忙於處理攻擊者僞造的TCP連接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率非常之小),此時從正常客戶的角度看來,服務器失去響應,這種情況我們稱作:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)。

爲什麼TCP建立連接要三次握手

  • 首先得回答三次握手的目的是同步連接雙方的序列號和確認號並交換 TCP 窗口大小信息。
  • 然後可以回答爲什麼兩次握手不行,兩次握手可能因爲丟包而出現死鎖,假設在兩次握手場景中,C向S發送請求,S收到併發送確認請求給C,這時候S認爲連接已經建立,並開始發送數據給C,但是那個確認請求丟包了,C不認爲請求建立了,C當然會拒絕接受S發送來的數據,並且再去請求連接。這樣,一個資源就死鎖了。

設置TIME_WAIT的原因

  • 可靠地實現TCP全雙工連接的終止
  • TCP協議在關閉連接的四次握手過程中,最終的ACK是由主動關閉連接的一端(後面統稱A端)發出的,如果這個ACK丟失,對方(後面統稱B端)將重發出最終的FIN,因此A端必須維護狀態信息(TIME_WAIT)允許它重發最終的ACK。如果A端不維持TIME_WAIT狀態,而是處於CLOSED 狀態,那麼A端將響應RST分節,B端收到後將此分節解釋成一個錯誤(在java中會拋出connection reset的SocketException)。
    因而,要實現TCP全雙工連接的正常終止,必須處理終止過程中四個分節任何一個分節的丟失情況,主動關閉連接的A端必須維持TIME_WAIT狀態
  • 允許老的重複分節在網絡中消逝
  • TCP分節可能由於路由器異常而“迷途“,在迷途期間,TCP發送端可能因確認超時而重發這個分節,迷途的分節在路由器修復後也會被送到最終目的地,這個遲到的迷途分節到達時可能會引起問題。在關閉“前一個連接”之後,馬上又重新建立起一個相同的IP和端口之間的“新連接”,“前一個連接”的迷途重複分組在“前一個連接”終止後到達,而被“新連接”收到了。爲了避免這個情況,TCP協議不允許處於TIME_WAIT狀態的連接啓動一個新的可用連接,因爲TIME_WAIT狀態持續2MSL,就可以保證當成功建立一個新TCP連接的時候,來自舊連接重複分組已經在網絡中消逝。

大量 TIME_WAIT 產生的原因及解決辦法

原因:對於基於TCP的HTTP協議,關閉TCP連接的是Server端,這樣,Server端會進入TIME_WAIT狀態,可想而知,對於訪問量大的Web Server,會存在大量的TIME_WAIT狀態。

解決辦法:

  • 開啓socket重用,允許將TIME_WAIT的socket重新用於TCP連接
  • 開啓快速回收。

大量CLOSE_WAIT產生的原因及解決辦法

原因:對方關閉連接之後服務器程序自己沒有進一步發出ack信號。換句話說,就是在對方連接 關閉之後,程序裏 沒有檢測到,或者程序壓根就忘記了這個時候需要關閉連接,於是這個資源就一直被程序佔着。

  • 解決辦法:
    具體問題具體解決,總結一句話就是在處理資源時一定要記住自己申請的資源要記得主動釋放。

參考:https://blog.csdn.net/shootyou/article/details/6622226

爲什麼TCP斷開連接要四次揮手

因爲tcp是全雙工模式,接收到FIN時意味將沒有數據再發來,但是還是可以繼續發送數據。

參考:https://blog.csdn.net/xifeijian/article/details/12777187

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章