白話解釋 TCP鏈接爲何須要三次握手?

本文只是爲了便於理解,作很是寬泛的描述,措辭不甚嚴謹,不當之處還望指正,感謝。
看本文章以前,建議對OSI模型已經TCP/IP不太瞭解的同窗們,看看我以前寫的 白話解釋 OSI模型,TLS/SSL 及 HTTPS
更多內容: 我的博客

一切爲了傳輸 UDP vs TCP

互聯網之因此偉大的緣由之一是解決了遠距離可靠傳輸信息的問題,既然要進行「互相」傳輸數據那麼確定是有必定的規則和協議的,TCP和UDP就是兩種普遍應用的傳輸協議,在這裏作一個簡單的比較:git

  • UDP (你把它想象成平郵信件),每每郵遞員會集中把信件放在郵局,好比一個學校的郵政,可是這種方式不可靠啊,由於這種平郵的信件總是容易「丟包」,也就是說,這種傳輸方式無法確保收件人必定能收到信件。

這不行啊,因此,人們就想到了一種更爲可靠的傳輸方式:github

  • TCP(你把它想象成快遞),快遞員能夠直接送貨上門,即便不送貨上門,可要給你打電話,檢查你的身份證,讓你簽字等等,確保你的包裹不會被丟失。因此,這種方式更「可靠」。

TCP vs UDP 誰更可靠

上面的例子也已經很清楚的看到,tcp(快遞)之因此可靠,是由於有種種的「檢查」機制,當快遞的「包裹」真正到達收件人手裏的時候,這個」傳輸「過程纔算完成,不然快遞小哥就「從新投遞「。那麼」UDP「(平郵信件)就無論這一套,反正根據信件上的地址把」傳輸的信件包「扔在最近的郵件或者上面所寫的信箱中就完事,至於隨後包裹到底到沒到收件人手中,這個UDP無論了。segmentfault

因此,到如今,咱們知道了,tcp傳輸數據比udp更加「可靠」!安全

TCP存在之於」互聯網「的意義

咱們如今能在互聯網上看文章,直播,視頻,娛樂,購物,甚至網上轉帳,固然,看直播的話,UDP協議仍是不錯滴,可是,若是涉及到金錢或者敏感數據,若是都像沒有一套「可靠」的傳輸協議,誰還敢在網上「轉帳」,「存儲信息」呢?tcp

咱們已經知道了,TCP存在的意義之一就是:」可靠的傳輸「,但同時要進行遠程通訊,」高效的傳輸「是必不可少的,最後,數據包在混沌險惡的互聯網中穿梭,」安全的傳輸「是必須的。code

因此,小結一下,TCP存在之於」互聯網「的意義有三點(重要的事情說三遍):視頻

- 讓數據進行」可靠「,」高效「,」安全「的傳輸
- 讓數據進行」可靠「,」高效「,」安全「的傳輸
- 讓數據進行」可靠「,」高效「,」安全「的傳輸
請注意:這裏所說的"高效"只是相對TCP本身而言,由於這個」高效「會和後面咱們會說到三次握手其中的第二步合併的握手相關,因此我在這裏提一下,其實,UDP會由於沒有了一些檢測機制會比TCP更加高效,快速。

必定的代價

都說」魚和熊掌不能兼得「,對於TCP來講更是如此,既然選擇了」可靠「,」高效「和」安全「做爲己任,那麼就必然要想一些辦法讓本身知足這些特徵,那麼TCP怎麼辦的呢?ip

可靠

數據的可靠性意味着接收方接收到了準確無誤的信息,若是中間有丟包,要有必定的機制讓發送方從新發送。TCP怎麼辦的呢?它是這麼辦的:get

發送方經過必定方式告訴接收方,所傳輸的數據包有多大,而後分幾回,好比:數據包總共100kb,而後分10次發送,這時候接收方就知道總共有10個數據包,同時發送方會在每一個數據包上標記上號碼,而後tcp從數據包1開始接受,逐次加一,知道接收到第十個結束,只有這10個所有確認收到了,接收方纔確認這個通訊完成,因此確保了數據的可靠性。博客

那麼問題來了,接收方怎麼知道數據包共100kb,而後又怎麼知道何時開始算是接受這個包?何時接受完成呢?這個時候就是第一次握手的開始,也能夠說是第一次交流的開始。

好比:張三(發送方)要發信息給李四(接收方)。

1. 張三:hi,李四,我想發送一個100kb的數據包,打算分10次發送,你那邊能接一下麼?
2. 李四:好的,收到,你發吧。
3. 張三:ok, 太棒了!
4. 張三:數據包1..2..3..4...5..6..7..8..9..10

那麼,可不能夠不打招呼直接發?也就是一次握手。固然能夠,就像UDP平郵似的,發唄,只不過有可能接收方收不到信息而已,發送方也不知道接收方收到仍是沒收到,就是得不到保障而已。

安全

你們有沒有以爲有什麼問題呢? 安全問題! 若是上面第四步張三在給李四發的時候,數據包編號每次老是從1開始,那麼豈不是太容易被猜想?若是這樣的話,」黑客小黑「能夠在與此同時發送帶有一樣編號的數據包,反正編號都從1開始,猜唄,由於TCP很傻,因此只要是編號相同就接受了,那樣就不太安全,黑客就能夠猜到這些數據包的編號了。

這裏說的數據包編號,實際上是在TCP頭信息中的」序列號「(sequence number),上面這種攻擊方式叫作:TCP序列號預測攻擊(TCP_sequence_prediction_attack)

因此,爲了防止序列號被踩到,咱們引入一種隨機序列號的方式進行提升,就是在張三和李四第一次握手的時候,張三同時在數據包中加入一個隨機序列號,發送給李四,而後由於李四收到張三的請求信息後還須要發送確認信息回給張三,這時候,李四就成了發送方了,因此李四也須要隨機出一個序列號給張三,爲的也是張三那邊可以安全可靠的獲得李四的信息,這裏咱們看到,在第二次握手的時候,李四須要:

  1. 確認張三的請求
  2. 發送本身的隨機序列號

原本是兩個步驟的,可是,tcp爲了」相對高效「的傳輸,就把這兩步」整合「到了一步中了,而後最後一步就是,張三收到來自李四的「確認」以及「隨機序列號」,而後再給李四發回一個「確認」消息,至此,三次握手結束,信息傳輸就開始了。

因此咱們把上面的栗子改進提升一下,就變成了:

1. 張三:hi,李四,我想發送一個100kb的數據包,打算分10次發送,爲了防止別人猜我發的數據包編號,這是我隨機出來的一個初始序列號,9381921,你那邊能接一下麼? (SYN)
2. 李四:好的,收到(ACK),這是我隨機出來的初始序列號,2342322,你發吧。(SYN)
3. 張三:ok, 太棒了!(ACK)
4. 張三:數據包9381921
5. 李四:收到數據包9381921,序列號:2342322
6. 張三:數據包9381922
7. 李四:收到數據包9381922,序列號:2342323
...

你們請注意上面我在對話中標註的:SYN及ACK,就是tcp三次握手的過程:

  1. 發送方給接收方發送SYN信號
  2. 接收方確認並回復給發送方SYN/ACK信號
  3. 發送方給接收方發送確認ACK信號

爲何TCP須要三次握手

我相信你們已經對上面三次握手流程有了一個比較清晰的認識了,那麼,咱們如今回到文章的主題,爲何TCP須要三次握手呢?爲何不是一次,兩次或四次呢?我不妨用一個問句來回答這個問題吧:若是是一次,兩次或四次,怎麼才能保證TCP的「可靠」,「安全」及「高效」的傳輸呢?

若是你有了這個問題的答案,那麼請必定告訴我!! ;)

相關文章
相關標籤/搜索