網路通信——TCP “三次握手“、“四次揮手“ 詳解

来源:https://www.cnblogs.com/smallroll/archive/2023/03/03/17176101.html
-Advertisement-
Play Games

前言 TCP三次握手和四次揮手是面試題的熱門考點,它們分別對應TCP的連接和釋放過程 1.TCP通信包含那幾步? TCP通信過程包括三個步驟:建立TCP連接通道,傳輸數據,斷開TCP連接通道 上圖主要包括三部分:*建立連接、傳輸數據、斷開連接。* 建立TCP連接很簡單,通過三次握手便可建立連接。 建 ...


前言

TCP三次握手和四次揮手是面試題的熱門考點,它們分別對應TCP的連接和釋放過程

1.TCP通信包含那幾步?

TCP通信過程包括三個步驟:建立TCP連接通道,傳輸數據,斷開TCP連接通道

在這裡插入圖片描述

上圖主要包括三部分:*建立連接、傳輸數據、斷開連接。*

  1. 建立TCP連接很簡單,通過三次握手便可建立連接。
  2. 建立好連接後,開始傳輸數據。TCP數據傳輸牽涉到的概念很多:超時重傳、快速重傳、流量控制、擁塞控制等等。
  3. 斷開連接的過程也很簡單,通過四次握手完成斷開連接的過程

2.三次握手建立連接

第一次握手: 客戶端發送syn包(seq=x)到伺服器,併進入SYN_SEND狀態,等待伺服器確認;

第二次握手: 伺服器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。

握手過程中傳送的包里不包含數據,三次握手完畢後,客戶端與伺服器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。

3.傳輸數據過程

  1. 超時重傳 超時重傳機制用來保證TCP傳輸的可靠性。每次發送數據包時,發送的數據報都有seq號,接收端收到數據後,會回覆ack進行確認,表示某一seq 號數據已經收到。發送方在發送了某個seq包後,等待一段時間,如果沒有收到對應的ack回覆,就會認為報文丟失,會重傳這個數據包。
  2. 快速重傳 接受數據一方發現有數據包丟掉了。就會發送ack報文告訴發送端重傳丟失的報文。如果發送端連續收到標號相同的ack包,則會觸發客戶端的快速重 傳。比較超時重傳和快速重傳,可以發現超時重傳是發送端在傻等超時,然後觸發重傳;而快速重傳則是接收端主動告訴發送端數據沒收到,然後觸發發送端重傳。
  3. 流量控制 這裡主要說TCP滑動窗流量控制。TCP頭裡有一個欄位叫Window,又叫Advertised-Window,這個欄位是接收端告訴發送端自己 還有多少緩衝區可以接收數據。於是發送端就可以根據這個接收端的處理能力來發送數據,而不會導致接收端處理不過來。滑動窗可以是提高TCP傳輸效率的一種機制。
  4. 擁塞控制 滑動窗用來做流量控制。流量控制只關註發送端和接受端自身的狀況,而沒有考慮整個網路的通信情況。擁塞控制,則是基於整個網路來考慮的。

4.四次揮手斷開連接

第一次揮手: 主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發數據了(當然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但此時主動關閉方還可以接受數據。

第二次揮手:被動關閉方收到FIN包後,發送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號)。

第三次揮手: 被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。

第四次揮手: 主動關閉方收到FIN後,發送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。

5.常見面試問題

【問題1】為什麼連接的時候是三次握手,關閉的時候卻是四次揮手?

答:因為當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回覆一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

【問題2】為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網路是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最後的ACK回覆,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重覆發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之後進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網路中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連接。

【問題3】為什麼不能用兩次握手進行連接?

答:3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。

現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作為例子,考慮電腦S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認為連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認為連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重覆發送同樣的分組。這樣就形成了死鎖。

【問題4】如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

答:TCP還設有一個保活計時器,顯然,客戶端如果出現故障,伺服器不能一直等下去,白白浪費資源。伺服器每收到一次客戶端的請求後都會重新複位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,伺服器就會發送一個探測報文段,以後每隔75分鐘發送一次。若一連發送10個探測報文仍然沒反應,伺服器就認為客戶端出了故障,接著就關閉連接。

總結

小捲聊開發,一個專註於技術、面試,偶爾發點生活的公眾號,關註我,一起變強!!!
image

本文來自博客園,作者:SmallRoll(小捲),轉載請註明原文鏈接:https://www.cnblogs.com/smallroll/p/17176101.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MyBatis緩存 mybatis – MyBatis 3 | cache MyBatis 一級緩存全詳解(一) MyBatis 內置了一個強大的事務性查詢緩存機制,它可以非常方便地配置和定製。 為了使它更加強大而且易於配置,我們對 MyBatis 3 中的緩存實現進行了許多改進。 1.一級緩存 1 ...
  • for迴圈 迴圈的作用與分類 作用:讓代碼更加高效的重覆運行 分類:for迴圈和while迴圈 for迴圈結構 for 臨時變數 in 可迭代對象: 重覆執行的代碼1 重覆執行的代碼2 ... 可迭代對象 = 一個容器或者序列 # 遍歷字元串 for i in 'Python': print(i) ...
  • 現象 系統根據指定的日期範圍(LocalDateTime)查詢資料庫,結果與直接將SQL語句查詢不一致,系統查詢的並不是期望日期範圍的數據。 通過 LocalDateTime、LocaDate、LocalDate 作為時間插入數據時,時間不對 解決 更換 mysql 的驅動包版本在 8.0.22及以 ...
  • Spring提供的事務使用起來很方便,一個@Transactional註解就搞定全部,但是如果不註意,也會踩坑 提到事務就應該想到至少以下幾點: 1、在事務方法中加鎖,可能會導致鎖失效 無論是JVM自帶的鎖,還是分散式鎖,都有可能出現沒鎖住的情況 原因是解鎖先於事務提交,一旦鎖釋放後其它線程就可以獲 ...
  • 目錄 ElasticSearch 實現分詞全文檢索 - 概述 ElasticSearch 實現分詞全文檢索 - ES、Kibana、IK安裝 ElasticSearch 實現分詞全文檢索 - Restful基本操作 --待發佈 ElasticSearch 實現分詞全文檢索 - Java Spring ...
  • 摘要:本文將以Sermant的SpringBoot 註冊插件的性能測試及優化過程為例,分享在Java Agent場景如何進行更好的性能測試優化及在Java Agent下需要著重註意的性能陷阱。 作者:欒文飛 高級軟體工程師 一、背景介紹 Sermant是一個主打服務治理領域的Java Agent框架 ...
  • PHP語言線上運行編譯,是一款可線上編程編輯器,在編輯器上輸入PHP語言代碼,點擊運行,可線上編譯運行PHP語言,PHP語言代碼線上運行調試,PHP語言線上編譯,可快速線上測試您的PHP語言代碼,線上編譯PHP語言代碼發現是否存在錯誤,如果代碼測試通過,將會輸出編譯後的結果。 該線上工具由IT寶庫提 ...
  • Vue 3 備忘清單 Vue 3漸進式 JavaScript 框架 Vue 3 備忘清單的快速參考列表,包含常用 API 和示例入門,為開發人員分享快速參考備忘單。 開發速查表大綱 入門 介紹 創建應用 應用實例 通過 CDN 使用 Vue 使用 ES 模塊構建版本 模板語法 文本插值 原始 HTM ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...