banner
Bai

Bai

写代码菜的一批 🤣
twitter
telegram
tg_channel
pixiv
github
bilibili
whatsapp

TCP/IP協議十五問

一、什麼是網路層?#

TCP 網路分層一般分為四層,當然也有說法是五層

  1. 應用層(HTTP):封裝資料包
  2. 傳輸層(TCP):增加 TCP 頭部,包含端口號等資訊
  3. 網路層(IP):增加 IP 頭部,包含 IP 地址等資訊
  4. 網路介面層(ARP):增加以太網頭部,包含 MAC 地址等資訊

網路分層的優點:

  • 各層獨立:限制了依賴關係的範圍,各層之間使用標準化的介面,各層不需要知道上下層是如何工作的,增加或者修改一個應用層協議不會影響傳輸層協議;
  • 靈活性:比如路由器不需要應用層和傳輸層,分層以後路由器就可以只用加載更少的幾個協議層
  • 易於測試和維護:提高了可測試性,可以獨立的測試特定層,某一層有了更好的實現可以整體替換掉;
  • 能促進標準化:各層職能清晰,方便標準化;

二、TCP 的三次握手?為什麼不是兩次或者四次?#

  1. 客戶端向服務端發送 SYN,seq = x;
  2. 服務端向客戶端發送 SYN,seq = y, ACK = x+1;
  3. 客戶端向服務端發送 ACK = y+1;

兩次不行因為如果只做兩次無法確定服務端的接收能力;
兩次握手後建立連接,有可能導致由於時延產生的多次連接建立,導致資源浪費;
四次的話沒必要,會導致資源浪費。

三、TCP 的四次揮手?為什麼不能是三次?#

  1. 客戶端向服務端發送 FIN,seq = x+2,ACK = y+1;
  2. 服務端向客戶端發送 ACK = x+3;
  3. 服務端發送完剩餘數據後,再向客戶端發送 FIN,seq = y+1;
  4. 客戶端向服務端發送 ACK = y+2;

三次不行,會導致服務端的 ACK 和 FIN 將延遲發送,如果延遲時間過長,客戶端將再次重發斷開請求,導致資源浪費。

四、為什麼 SYN/FIN 不包含數據卻要消耗一個序列號?#

凡是需要對端確認的,一定消耗 TCP 報文的序列號;

五、什麼是半連接隊列?什麼是 SYN Flood 攻擊?#

客戶端大量偽造 IP 發送 SYN 包,服務端回復的 ACK+SYN 去到了一個(未知)的 IP 地址,勢必會造成服務端大量的連接處於 SYN_RCVD 狀態,而伺服器的半連接隊列大小也是有限的,如果半連接隊列滿,也會出現無法處理正常請求的情況。

六、TCP 快速打開的原理?#

TCP 快速打開(TCP Fast Open,TFO)
TFO 是在原來 TCP 協議上的擴展協議,它的主要原理就在發送第一個 SYN 包的時候就開始傳數據了,不過他要求當前客戶端之前已經完成過正常的三次握手。

快速打開分為兩個階段:請求 Fast Open Cookie 和 真正開始 TCP Fast Open

TCP Fast Open 的優勢
可以利用握手去除一個往返的 RTT 和防止 SYN-Flood 之類的攻擊

七、TCP 報文中的時間戳有什麼用?#

TCP Timestamps Option 由四部分構成:類別、長度、發送方時間戳、回顯時間戳

第一用於計算 RTT,第二防止序列號的回環問題,即使使用的序列號相同,也可以通過時間戳來對不同的包進行區分。

八、TCP 的超時重傳時間是如何計算的?#

超時重傳時間:Retransmission TimeOut, 簡稱 RTO

經典解決方法
適用於 RTT 較小的情況,SRTT (smoothed round trip time)。
利用最新一次的 RTT 對 SRTT 時間進行更新
SRTT = α × SRTT + (1-α)× RTT

九、TCP 流量控制?#

把發送的數據放到發送緩衝區,把接收的數據放到接收緩衝區。通過實際接收緩衝區的大小,控制發送端的發送。
接收端會告知客戶端自己接收窗口,也就是接收緩衝區中空閒的部分。

發送端的數據包的狀態:

  • 已發送且已確認
  • 已發送未確認的
  • 未發送但接收端可以接受的(接收端有空間接受)
  • 未發送且不可以發送(接收端沒空間接受)

發送端速度較慢:存在大量待發送的字節;
發送端速度較快:存在大量待確認的字節;

十、TCP 的 keep-alive 原理?#

定時發送探測包來探測連接的對端是否存活,但是 keepalive 默認設置的時間過長,7200s 沒有實際意義,一般在應用層做心跳機制。

那什麼是心跳機制?
定時向服務端發送消息,能響應服務端的消息

長連接業務場景

  • 遊戲
  • 即時通訊
    在沒有心跳包機制的情況下,網路若掉線,對方不可知;
    如果客戶端掉線,服務端不知道,還維持連接,就是額外的無效系統開銷。

為什麼需要心跳包:

  • 在 NAT、防火牆網路中裝設備,保存信道記錄;
  • 及時發現對方網路斷開,以便及時採取措施;

如何實現心跳包

  • TCP 層面的心跳包,只能夠驗證網路連接是否異常;
  • 應用層層面的心跳包,驗證服務接口是否異常;

為什麼不採用 TCP 層面?
應用層的連接如果成功,那麼 TCP 所在的傳輸層必定成功。

十一、TCP 中的端口號?#

  • 源端口:本地端口
  • 目標端口:伺服器端口
    最大 65536 個,所以是 0-65535

以下是一些常見的端口號:

  • 21:FTP(檔案傳輸協議)端口,用於檔案上傳和下載。
  • 22:SSH(安全外殼協議)端口,用於安全遠程登錄和執行命令。
  • 25:SMTP(簡單郵件傳輸協議)端口,用於電子郵件傳輸。
  • 80:HTTP(超文本傳輸協議)端口,用於 Web 瀏覽器訪問網站。
  • 110:POP3(郵局協議版本 3)端口,用於電子郵件客戶端接收郵件。
  • 143:IMAP(互聯網消息訪問協議)端口,用於電子郵件客戶端接收郵件。
  • 443:HTTPS(超文本傳輸安全協議)端口,用於安全的 Web 瀏覽器訪問網站。
  • 3306:MySQL 數據庫端口,用於數據存儲和檢索。
  • 3389:Microsoft 遠程桌面端口,用於遠程管理和控制計算機。
    這只是一小部分常用的端口號,實際上有許多其他端口號可以用於各種不同的通信協議和應用程序。

十二、TCP 場景問題#

問題 1
AB 兩個主機之間建立了一個 TCP 連接,A 主機發給 B 主機兩個 TCP 報文,大小分別是 500 和 300,第一個報文的序列號是 200,那麼 B 主機接收兩個報文後,返回的確認號是多少?
500+300+200 = 1000

問題 2
收到 IP 數據包解析後,如何知道應該投遞到上層中的哪個協議(是 TCP 還是 UDP)?
IP 報文頭中有協議字段,TCP6,UDP17

問題 3
TCP 提供了一種字節流服務,而收發雙方都不保持記錄的邊界,應用程序應該如何提供他們自己的記錄標識呢?

應用程序使用自己約定的規則來標識消息的邊界,比如有一些使用回車+換行(“\r\n”),比如 Redis 的通信協議;

十三、TCP 和 UDP 的區別?#

TCP 是一個面向連接的、可靠的、基於字節流的傳輸層協議;
UDP 是一個面向無連接的傳輸層協議;

  • 面向連接:指的是客戶端和服務端的連接,在通信前通過三次握手建立連接;

  • 可靠性:

  1. TCP 有狀態:TCP 會精確記錄那些數據發送了,哪些數據已被接收,那些數據未被接收,並且保證數據包按序到達,不允許差錯;
  2. TCP 可控制:如果遇到丟包或者網路不佳,TCP 會根據具體情況自行調整,控制自己的發送速度或者重發。

十四、Telnet 和 netstat 的用法#

  • 檢查遠端端口是否打開,其語法:telnet [ip] [port]
  • 主要用於查詢網路情況,如: netstat -ano

十五、Tcpdump 和 wireshark#

用於抓包,例如可以查看三次握手和四次揮手等

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。