再有面試官問TCP三次握手,你就拿這篇文章糊他臉(輕鬆幽默帶你理解TCP的通信原理:深度好文)

面試情景

一天,你進入了一個大廠面試。坐立不安之中,一個禿頭中年男子,穿着一個發灰了的格子襯衫,戴着一副鏡片厚9mm的眼鏡,穩如磐石突然朝着你說到:“就是你這個小毛頭來面試吧。”

心裏一驚,這怕不是神仙級架構師。但還是故作鎮定:“面試官您好,我是xxx…”

面試過程中……面試官隨手拋來一句:“簡單說說 TCP 三次握手吧。”。

簡單說說???嗯,面試官人還不錯。
再加上我面試前的精心準備,和飽讀詩書的才華,和揮斥方遒的瀟灑帥氣,一定能深深折服他。
於是:“ TCP 三次握手很簡單,

  1. 客戶端首先生成一個 SYN 報文,隨機生成一個 seq,發給服務端。
  2. 服務端生成一個 SYN 報文,隨機生成一個 seq,返回一個 ACK(爲客戶端的 seq + 1),發給客戶端。
  3. 客戶端再返回一個ACK(爲服務端的 seq + 1)和 seq(爲先前的 seq + 1,也是服務端返回的 ACK 的值)。

三次握手就完成了。”

面試官再問:

  1. SYN 是啥
  2. seq 是啥
  3. ACK 是啥
  4. 爲啥返回的 ACK = seq + 1
  5. TCP 3 次握手可以攜帶數據嗎
  6. 爲啥一定要 “3” 次,2 次不行嗎
  7. 爲啥斷開要 4 次,不能 3 次嗎
  8. 如果報文段丟失怎麼辦
  9. 報文超長延遲怎麼辦
  10. 網絡擁塞怎麼辦

這都啥?????
“你回去等通知吧。”

<瑟瑟發抖>

下面進入正題,如果上面的題你都理解,能夠熟練回答,那對於 TCP 原理你瞭解得已經比較透徹了。
背三次握手的過程可能很簡單,但是面試官細問,那你就露餡了,所以得深入理解纔行。
要了解 TCP 的三次握手,你首先需要了解 TCP 的通信原理。
(以下所有圖片摘自《計算機網絡 自頂向下方法》)

我們先看 TCP 報文段結構(不用全部都理解)
我們只需要關注到,其中有

  • 首部(只需要知道有這個東西)
  • 序號字段 (32比特)
  • 確認號字段 (序號和確認號用來實現:傳輸可靠)(32比特)

下面進行深入解釋
圖片摘自
爲了實現通信的可靠,就需要一方對另一方的發送的數據進行:回覆確認。

  • 比如:
  • A 對 B 說,我要去你家啦。
    (這時 A 還不知道 B 有沒有收到 A 要過去的消息,所以他不能隨意去別人家)
  • (直到)B 對 A 說,好的,請來吧。
    (這時 B 就可以確認 A 已經收到了消息,他就可以放心的過去了)

這就是 TCP 來實現通訊可靠的原理。
在 TCP 通訊中。

  • 舉個例子
  • A 發送了一條數據報文,Seq = 100,data 長度爲 20
  • B 接收成功,返回的 ACK = 120。
    (返回的 ACK = 發送的 Seq + data 長度)
  • 如果 A 要再次發送,則 Seq = 120。
    (根據收到的 ACK = 120 可得知數據發送序號已經到 120 了,便可以接着發送)

這裏返回的 ACK = 發送的 Seq + data 的長度。(用來表示全部收到)
在 TCP 中,兩邊都是有 Seq 和 ACK 和各自的 data 的。

  • 以《計算機網絡 自頂向下方法》書中的例子來說明
  • A 和 B 都發送了一個一個字符 ‘ C ’ 給對方(也就是長度爲 1 )
  • A 發送 Seq = 42,ACK = 79,data = ‘ C ’
  • B 接收了成功之後,返回給 B 的 ACK = 43,data = ‘ C ’ 自己的 Seq = 79
    (因爲 A 返回給他的 ACK = 79,說明 B 之前的發送序號已經達到到了 79,所以 Seq = 79)
  • A 此時沒有數據要發送,所以返回時,只需要設置 ACK = 80,Seq = 43。
    (返回時可以不帶數據,ACK 用來確認,Seq 只是必須包含在內而已)
    在這裏插入圖片描述
    再舉個例子
  • A 發送了三條報文給 B
  • Seq = 92,數據有 8 個字節
  • 那第二條 Seq 一定 = 100,此時數據有 20 個字節
  • 第三條 Seq = 120,數據有 30 個字節
  • A 等待 B 返回的 ACK
  • B 返回一條 ACK = 100,一條 ACK = 120,一條 ACK = 150
  • 此時,正常情況下會收到三條 ACK 的返回。
    不過 A 只需要收到一條 ACK = 150 即可
    (ACK = 150 表示所有的數據都已經收到)
  • 可能網絡各種原因,導致丟失報文。
    比如 ACK = 100,ACK = 120, 丟失。但是 ACK = 150 收到,則可以確認數據全部傳輸成功。
    若只收到 ACK = 120,則表示前兩條數據傳輸成功,第三條報文出現問題。

現在,我們便已經明白了 TCP 傳輸的原理。
而 TCP 建立連接的過程,僅僅是發送特殊的報文來表示而已。
所以很容易可以明白。

TCP 三次握手過程

簡單的說就是:

  1. 客戶端向服務端發起連接請求
  2. 服務端回覆確認
  3. 服務端向客戶端發起連接請求
  4. 客戶端回覆確認

乍一看好像有 4 步,實際上,2、3兩步可以成爲一步。
服務端回覆消息的時候,可以既確認客戶端的請求,也發起自己的請求。
所以就是三次握手了

但跟面試官不能只說得這麼扯皮,下面說得嚴謹一些

  1. 客戶端 先向 服務端 發送一條特殊的報文段
    其中不包含應用層數據
    !在報文段首部中的一個標誌位(即 SYN 比特)被置爲 1(SYN = 1)
    Seq = 隨機選擇一個初始序號 client_isn
  2. 服務端 從收到的報文中提取出 SYN 比特位,發現這是一條請求連接的報文
    於是爲該 TCP 連接分配緩存和變量
    返回給 客戶端 的報文也不能包含應用層數據
    報文的 SYN 比特也設置爲 1(SYN = 1)
    ACK = client_isn + 1(也就是 C 發來的 Seq + 1)
    Seq = server_isn(服務器自己的初始序號)
  3. 客戶端 收到 服務端 發來的報文
    給該鏈接分配緩存變量
    返回報文給服務器表示確認,ACK = server_isn + 1。
    SYN = 0,表示連接成功(以後的 SYN 都爲 0)
    這時的報文已經可以包含應用層數據了

在這裏插入圖片描述

四次揮手

同理,要理解四次揮手也很簡單。

  1. 客戶端向服務端發起分手請求
  2. 服務端回覆確認
  3. 服務端向客戶端發起分手請求
  4. 客戶端回覆確認

???
爲啥 2、3 不能放在一塊做 3 次 “分手”呢
實際上也是可以的。
只是因爲一般來說,服務端在回覆確認了中斷連接的報文之後,很可能還有數據沒有發送完。只有等到要發送給 “ 心愛的ta ” 的數據都發送完了之後,纔會發送 “ 分手 ” 請求。
所以,先給對方回一個確認,然後過一會發送完數據,再發送中斷連接報文。
中斷報文則是 FIN 報文。如圖:
在這裏插入圖片描述
現在我已經理解了 TCP 的通訊原理了。
但是還有問題沒有解決。
比如:

  • 如果 A 給 B 發了報文,但是 B 一直沒收到?
  • 或者 A 給 B 發了多個報文,但 B 只收到一部分?
  • 或者 A 給 B 發了報文,隔了很久很久 B 才收到?
  • 或者 A 給 B 發了報文,B 的回信丟失了?

那就需要重新發送,規則是
根據發送時間,計算是否超時
根據 B 返回的 ACK 判斷,ACK 爲多少,則代表 B 確認了多少,A 就要讓 Seq = ACK,重新發送從該位置起,之後的數據

假設 A 給 B 發送了報文,Seq = 92,包含 8 個字節數據
那麼 A 需要 B 返回的 ACK = 100 來確認
假設 B 的確認報文丟失了,或者傳輸時間過長。
那麼 A 等了半天一直沒有收到確認,則會將消息重新發送。
B 收到第二條一樣的報文,知道了 A 沒有得到確認,則會再次返回 ACK 來確認
在這裏插入圖片描述
假設 A 發送了兩個報文
Seq = 92,8 個字節
Seq = 100,20 個字節
那麼 A 就在等待 ACK = 100 和 ACK = 120 的報文。
可是 A 等了半天沒反應,準備重發。
A 發送 Seq = 92,8 個字節
然後 A 就收到了 ACK = 100 和 ACK = 120
這時,第二條報文就不用再重發,已經保證了數據全部傳輸成功
而 B 收到重發的請求,雖然是第一條,但是仍需要發 ACK = 120 告知全部完成
(感覺還是看圖最清楚,語言解釋反而麻煩)
在這裏插入圖片描述
假設 A 發送的兩段報文
Seq = 92,8 個字節
Seq = 100,20 個字節
那麼 A 就在等待 ACK = 100 和 ACK = 120 的報文。
但是 ACK = 100 的報文丟失
不過 ACK = 120 到達則代表了 120 以前的全部成功(所以 ACK = 100 丟了無所謂)
在這裏插入圖片描述

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