深入淺出TCP/IP協議

什麼是TCP/IP協議?

TCP/IP 是一類協議系統,它是用於網絡通信的一套協議集合.傳統上來說 TCP/IP 被認爲是一個四層協議

1. TCP/IP協議模型?

在這裏插入圖片描述
通過圖上我們可以知道TCP/IP是一個協議集合,且其模型是四層模型: 應用層,傳輸層, 網絡層, 網絡接口層。於是我們知道TCP/IP協議不是單指的是TCP 和 IP,而是一個協議系統。但單獨的TCP就是網絡層的TCP,IP就是傳輸層的IP

2.TCP/IP協議的系統是如何工作的?

在這裏插入圖片描述

  1. 上圖清楚地表示了TCP/IP協議中每個層的作用,而TCP/IP協議通信的過程其實就對應着數據入棧與出棧的過程。入棧的過程,數據發送方每層不斷地封裝首部與尾部,添加一些傳輸的信息,確保能傳輸到目的地。出棧的過程,數據接收方每層不斷地拆除首部與尾部,得到最終傳輸的數據。
  2. 在這裏插入圖片描述

4. TCP 和 UDP 的區別?

傳輸層提供了兩種到達目標網絡的方式

  • 傳輸控制協議(TCP):提供了完善的錯誤控制和流量控制,能夠確保數據正常傳輸,是一個面向連接的協議。
  • 用戶數據報協議(UDP):只提供了基本的錯誤檢測,是一個無連接的協議。

特點:
1)UDP:
把數據打包
數據大小有限制(64k)
不建立連接
速度快,但可靠性低

2)TCP:
建立連接通道
數據大小無限制
速度慢,但是可靠性高

5. TCP是如何保證可靠性的?

TCP協議保證數據傳輸可靠性的方式主要有:
(https://blog.csdn.net/liuchenxia8/article/details/80428157詳細解釋)

  1. 校驗和
  2. 序列號
  3. 確認應答
  4. 超時重傳
  5. 連接管理
  6. 流量控制
  7. 擁塞控制

3. TCP的三次握手和四次揮手?

TCP的三次握手🤝建立連接和四次揮手👋斷開連接,相信很多人都聽說過,也都看過相關的內容,本篇是爲了記錄自己對與這兩種操作的理解。
在進入正式內容之前,先來看幾個符號的概念:

  • 序列號seq: 用來標記數據段的順序,TCP把連接中發送的所有數據字節都編上一個序號,第一個字節的編號由本地隨機產生;給字節編上序號後,就給每一個報文段指派一個序號;序列號seq就是這個報文段中的第一個字節的數據編號。
  • 確認號ack: 期待收到對方下一個報文段的第一個數據字節的序號;序列號表示報文段攜帶數據的第一個字節的編號;而確認號指的是期望接收到下一個字節的編號;因此當前報文段最後一個字節的編號+1即爲確認號。
  • 確認ACK: 僅當ACK=1時,確認號字段纔有效。ACK=0時,確認號無效
  • 同步SYN: 連接建立時用於同步序號。當SYN=1,ACK=0時表示:這是一個連接請求報文段。若同意連接,則在響應報文段中使得SYN=1,ACK=1。因此,SYN=1表示這是一個連接請求,或連接接受報文。SYN這個標誌位只有在TCP建產連接時纔會被置1,握手完成後SYN標誌位被置0。
  • 終止FIN: 用來釋放一個連接。FIN=1表示:此報文段的發送方的數據已經發送完畢,並要求釋放運輸連接
三次握手

首先進入一下情景:
我正在飯店裏和朋友喫飯,喝的正嗨的時候,女朋友打電話過來,飯店裏有很多人,環境原因聽不太清電話裏的聲音:

  • 我:能聽到我的聲音嗎?
  • 女:能聽到,大點聲,你能聽到我講話嗎?
  • 我:能聽到,
    如此這般,才能保證雙方都能聽到聲音,才能繼續對話呀。

TCP是面向連接的,無論哪一方向另一方發送數據之前,都必須先在雙方之間建立一條連接。在TCP/IP協議中,TCP 協議提供可靠的連接服務,連接是通過三次握手🤝進行初始化的。三次握手🤝的目的是同步連接雙方的序列號和確認號並交換 TCP窗口大小信息。由此我們來對應客戶端與服務器之間的建立連接:
在這裏插入圖片描述

  • 第一次握手🤝: 客戶端向服務器發出連接請求報文,這時報文首部中的同部位SYN=1,同時隨機生成初始序列號 seq=x,此時,客戶端進程進入了 SYN-SENT狀態,等待服務器的確認。
  • 第二次握手🤝: 服務器收到請求報文後,如果同意連接,則發出確認報文。確認報文中應該 ACK=1,SYN=1,確認號是ack=x+1,同時也要爲自己隨機初始化一個序列號 seq=y,此時,服務器進程進入了SYN-RCVD狀態,詢問客戶端是否做好準備。
  • 第三次握手🤝: 客戶端進程收到確認後,還要向服務器給出確認。確認報文的ACK=1,ack=y+1,此時,連接建立,客戶端進入ESTABLISHED狀態,服務器端也進入ESTABLISHED狀態。

那麼問題來了?那爲什麼要進行三次握手?

假如現在客戶端想向服務端進行握手,它發送了第一個連接的請求報文,但是由於網絡信號差或者服務器負載過多,這個請求沒有立即到達服務端,而是在某個網絡節點中長時間的滯留了,以至於滯留到客戶端連接釋放以後的某個時間點纔到達服務端,那麼這就是一個失效的報文,但是服務端接收到這個失效的請求報文後,就誤認爲客戶端又發了一次連接請求,服務端就會想向客戶端發出確認的報文,表示同意建立連接。

假如不採用三次握手,那麼只要服務端發出確認,表示新的建立就連接了。但是現在客戶端並沒有發出建立連接的請求,其實這個請求是失效的請求,一切都是服務端在自相情願,因此客戶端是不會理睬服務端的確認信息,也不會向服務端發送確認的請求,但是服務器卻認爲新的連接已經建立起來了,並一直等待客戶端發來數據,這樣的情況下,服務端的很多資源就沒白白浪費掉了。採用三次握手的辦法就是爲了防止上述這種情況的發生,比如就在剛纔的情況下,客戶端不會向服務端發出確認的請求,服務端會因爲收不到確認的報文,就知道客戶端並沒有要建立連接,那麼服務端也就不會去建立連接,這就是三次握手的作用。

四次揮手

來,再次進入以下情景:
假如有一天我想要自由了,我就跟我的女朋友提出分手的要求:

  • 我:我要自由,自由萬歲,分手吧
  • 女:好,你要分手是吧
    然後她會罵我渣啊來發泄,或者試圖挽留,在經過冷靜之後:
  • 女:那就這樣吧,分
  • 我:好的,分

至此就各奔東西,互相安好,相忘於江湖。
當客戶端和服務器通過三次握手建立了TCP連接以後,當數據傳送完畢,爲了防止資源浪費肯定要斷開TCP連接,那對於TCP的斷開連接,這裏就有了斷開連接的四次揮手。[

  • 第一次揮手👋: 客戶端進程發出連接釋放FIN報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號爲seq=x,此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。
  • 第二次揮手👋: 服務端進程收到連接釋放FIN報文,發出確認ACK報文,ACK=1,ack=x+1,並且帶上自己的序列號seq=y,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。此時,服務端通知高層的應用進程,客戶端向服務端的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務端若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。客戶端收到服務端的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文,在這之前依然可以接收服務端發送過來的最後的數據。
  • 第三次揮手👋: 服務端將最後的數據發送給客戶端完成後,就向客戶端發送連接釋放FIN報文,FIN=1,ack=x+1,此時的序列號爲seq=z,此時,服務端就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
  • 第四次揮手👋: 客戶端接收到服務端的連接釋放FIN報文後,必鬚髮出確認報文,ACK=1,ack=z+1,而自己的序列號是seq=x+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。此時服務端收到客戶端發送過來的確認報文,就立即撤銷自己的傳輸控制塊TCB,進入CLOSED狀態,注意此時的TCP連接還沒有釋放,必須經過2MSL(最長報文段壽命)的時間後,客戶端沒有收到服務端發來的任何數據,證明服務端已正常關閉,此時客戶端會撤銷相應傳輸控制塊TCB後,進入CLOSED狀態。至此,TCP的連接才真正的斷開了。(服務端結束TCP連接的時間要比客戶端稍微早一些)
爲什麼斷開連接需要四次揮手👋呢,像建立連接的時候一樣,三次行不行呢?
  • TCP協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP是全雙工 模式,這就意味着,在客戶端想要斷開連接時,客戶端向服務端發送FIN報文,只是表示客戶端已經沒有數據要發送了,但是這個時候客戶端還是可以接收來自服務端的數據。
  • 當服務端接收到FIN報文,並返回ACK報文,表示服務端已經知道了客戶端要斷開連接,客戶端已經沒有數據要發送了,但是這個時候服務端可能依然有數據要傳輸給客戶端。
  • 當服務端的數據傳輸完之後,服務端會發送FIN報文給客戶端,表示服務端也沒有數據要傳輸了,服務端同意關閉連接,之後,客戶端收到FIN報文,立即發送給客戶端一個ACK報文,確定關閉連接。在之後,客戶端和服務端彼此就愉快的斷開了這次的TCP連接。
  • 或許會有疑問,爲什麼服務端的ACK報文和FIN報文都是分開發送的,但是在三次握手的時候卻是ACK報文和SYN報文是一起發送的,因爲在三次握手的過程中,當服務端收到客戶端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是在關閉連接時,當服務端接收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴客戶端,你發的FIN報文我收到了,只有等到服務端所有的數據都發送完了,才能發送FIN報文,因此ACK報文和FIN報文不能一起發送。所以斷開連接的時候才需要四次揮手來完成
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章