TCP消息傳輸可靠性保證

TCP鏈接與斷開 -- 三次握手&四次揮手

三次握手

TCP 提供面向有連接的通信傳輸。面向有連接是指在數據通信開始之前先做好兩端之間的準備工作。

所謂三次握手是指建立一個 TCP 連接時需要客戶端和服務器端總共發送三個包以確認連接的建立。在socket編程中,這一過程由客戶端執行connect來觸發。

第一次握手:客戶端將標志位SYN置為1,隨機產生一個值seq=J,并將該數據包發送給服務器端,客戶端進入SYN_SENT狀態,等待服務器端確認。

第二次握手:服務器端收到數據包后由標志位SYN=1知道客戶端請求建立連接,服務器端將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,并將該數據包發送給客戶端以確認連接請求,服務器端進入SYN_RCVD狀態。

第三次握手:客戶端收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,并將該數據包發送給服務器端,服務器端檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,客戶端和服務器端進入ESTABLISHED狀態,完成三次握手,隨后客戶端與服務器端之間可以開始傳輸數據了。

四次揮手

四次揮手即終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。在socket編程中,這一過程由客戶端或服務端任一方執行close來觸發。

由于TCP連接是全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務后,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味著這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉。

1. 客戶端進程發出連接釋放報文,并且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等于前面已經傳送過來的數據的最后一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。

2. 服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,并且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處于半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。

3. 客戶端收到服務器的確認請求后,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最后的數據)。

4. 服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由于在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了LAST-ACK(最后確認)狀態,等待客戶端的確認。

5. 客戶端收到服務器的連接釋放報文后,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2??MSL(最長報文段壽命)的時間后,當客戶端撤銷相應的TCB后,才進入CLOSED狀態。

6. 服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB后,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。

TCP/IP中的數據包

每個分層中,都會對所發送的數據附加一個首部,在這個首部中包含了該層必要的信息,如發送的目標地址以及協議相關信息。通常,為協議提供的信息為包首部,所要發送的內容為數據。在下一層的角度看,從上一層收到的包全部都被認為是本層的數據。

網絡中傳輸的數據包由兩部分組成:一部分是協議所要用到的首部,另一部分是上一層傳過來的數據。首部的結構由協議的具體規范詳細定義。在數據包的首部,明確標明了協議應該如何讀取數據。反過來說,看到首部,也就能夠了解該協議必要的信息以及所要處理的數據。

· ① 應用程序處理
首先應用程序會進行編碼處理,這些編碼相當于 OSI 的表示層功能;
編碼轉化后,郵件不一定馬上被發送出去,這種何時建立通信連接何時發送數據的管理功能,相當于 OSI 的會話層功能。

· ② TCP 模塊的處理
TCP 根據應用的指示,負責建立連接、發送數據以及斷開連接。TCP 提供將應用層發來的數據順利發送至對端的可靠傳輸。為了實現這一功能,需要在應用層數據的前端附加一個 TCP 首部。

· ③ IP 模塊的處理
IP 將 TCP 傳過來的 TCP 首部和 TCP 數據合起來當做自己的數據,并在 TCP 首部的前端加上自己的 IP 首部。IP 包生成后,參考路由控制表決定接受此 IP 包的路由或主機。

· ④ 網絡接口(以太網驅動)的處理
從 IP 傳過來的 IP 包對于以太網來說就是數據。給這些數據附加上以太網首部并進行發送處理,生成的以太網數據包將通過物理層傳輸給接收端。

· ⑤ 網絡接口(以太網驅動)的處理
主機收到以太網包后,首先從以太網包首部找到 MAC 地址判斷是否為發送給自己的包,若不是則丟棄數據。
如果是發送給自己的包,則從以太網包首部中的類型確定數據類型,再傳給相應的模塊,如 IP、ARP 等。這里的例子則是 IP 。

· ⑥ IP 模塊的處理
IP 模塊接收到 數據后也做類似的處理。從包首部中判斷此 IP 地址是否與自己的 IP 地址匹配,如果匹配則根據首部的協議類型將數據發送給對應的模塊,如 TCP、UDP。這里的例子則是 TCP。
另外嗎,對于有路由器的情況,接收端地址往往不是自己的地址,此時,需要借助路由控制表,在調查應該送往的主機或路由器之后再進行轉發數據。

· ⑦ TCP 模塊的處理
在 TCP 模塊中,首先會計算一下校驗和,判斷數據是否被破壞。然后檢查是否在按照序號接收數據。最后檢查端口號,確定具體的應用程序。數據被完整地接收以后,會傳給由端口號識別的應用程序。

· ⑧ 應用程序的處理
接收端應用程序會直接接收發送端發送的數據。通過解析數據,展示相應的內容。

TCP 中通過序列號與確認應答提高可靠性

在 TCP協議頭中,當發送端的數據到達接收主機時,接收端主機會返回一個已收到消息的通知。這個消息叫做確認應答(ACK)。當發送端將數據發出之后會等待對端的確認應答。如果有確認應答,說明數據已經成功到達對端。反之,則數據丟失的可能性很大。

在一定時間內沒有等待到確認應答,發送端就可以認為數據已經丟失,并進行重發。由此,即使產生了丟包,仍然能夠保證數據能夠到達對端,實現可靠傳輸。

未收到確認應答并不意味著數據一定丟失。也有可能是數據對方已經收到,只是返回的確認應答在途中丟失。這種情況也會導致發送端誤以為數據沒有到達目的地而重發數據。

此外,也有可能因為一些其他原因導致確認應答延遲到達,在源主機重發數據以后才到達的情況也屢見不鮮。此時,源主機只要按照機制重發數據即可。

對于目標主機來說,反復收到相同的數據是不可取的。為了對上層應用提供可靠的傳輸,目標主機必須放棄重復的數據包。為此我們引入了序列號。

序列號是按照順序給發送數據的每一個字節(8位字節)都標上號碼的編號。接收端查詢接收數據 TCP 首部中的序列號和數據的長度,將自己下一步應該接收的序列號作為確認應答返送回去。通過序列號和確認應答號,TCP 能夠識別是否已經接收數據,又能夠判斷是否需要接收,從而實現可靠傳輸。

TCP協議中得標識位整理

標識位:URG, ACK, PSH, RST, SYN, FIN 共6個每一個標識位都有自己得功能

標識

中文翻譯

含義

URG

緊急指針標識

為1標識緊急指針有效,為0則忽略緊急指針

ACK

確認序號標識

為1標識確認號有效,為0表示報文中不含確認消息可忽略確認號屬性

PSH

接收信號標識

為1標識帶有qush標識得數據指示接收方在收到該報文后,應盡快將該報文交給應用程序而不是在緩沖區排隊

SYN

同步序號標識

用于建立連接過程,在請求連接時,SYN=1和ACK=0標識該數據段沒有使用捎帶的消息確認域,而連接應答捎帶一個確認,即SYN=1和ACK=1

FIN

完成標識

用于釋放鏈接,為1表示發送當已經沒有數據發送了,即可關閉本次數據流

RST

重置鏈接標識

用于重置由于主機崩潰或其他原因導致的錯誤連接,或用于拒絕非法報文段和拒絕連接請求

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

算法模版,今天開始背

二分查找算法 int left_bound(int[] nums, int target) {int left 0, right nums.length - 1;// 搜索區間為 [left, right]while (left < right) {int mid left (right - left) / 2;if (nums[mid] < target) {// 搜索區間變為 [mid1, right]left mid 1;} else if …

ubuntu更換國內apt源

ubuntu必備操作 1 更換apt鏡像源 備份鏡像 cp /etc/apt/sources.list /etc/apt/sources.list.bak查看自己ubuntu版本 # 查看自己的codename #查看自己的ubuntu版本[注意關注&#xff1a;DISTRIB_CODENAME&#xff0c;發行代號] cat /etc/*release# DISTRIB_CODENAMEcosmic …

面試熱題(合并K個升序鏈表)

給定一個鏈表數組&#xff0c;每個鏈表都已經按升序排列。 請將所有鏈表合并到一個升序鏈表中&#xff0c;返回合并后的鏈表。 輸入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 輸出&#xff1a;[1,1,2,3,4,4,5,6] 解釋&#xff1a;鏈表數組如下&#xff1a; [1->4->5,1…

【軟件工程】面向對象方法-RUP

RUP&#xff08;Rational Unified Process&#xff0c;統一軟件開發過程&#xff09;。 RUP特點 以用況驅動的&#xff0c;以體系結構為中心的&#xff0c;迭代增量式開發 用況驅動 用況是能夠向用戶提供有價值結果的系統中的一種功能用況獲取的是功能需求 在系統的生存周期中…

解決在vue中img標簽不顯示圖片的問題

在vue中, 經常會遇到img標簽不展示的問題, 本人遇到兩種, 都是因為webpack打包, 導致找不到路徑, 所以不現實, 總結幾個可以解決本地圖片路徑顯示不出來的問題&#xff1a; 1.把圖片放在src同級的static文件夾下。 2.把圖片放在cdn上&#xff0c;把網絡地址存在imgUrl里&#x…

RabbitMQ: 詳解、使用教程和示例

RabbitMQ: 詳解、使用教程和示例 什么是 RabbitMQ&#xff1f; RabbitMQ 是一個開源的消息代理&#xff08;Message Broker&#xff09;軟件&#xff0c;它實現了高級消息隊列協議&#xff08;AMQP&#xff09;&#xff0c;用于在應用程序之間進行異步消息傳遞。它允許應用程…

uni-app日期選擇器

寫個簡單的日期選擇器&#xff0c;還沒搞樣式&#xff0c;所以有點丑 大概長這樣吧 首先是這個picker選擇器&#xff0c;mode選擇日期&#xff0c;end是寫一個范圍前日期&#xff0c;:end就是這個日期是動態變化的&#xff0c;還有change函數 <template><view>&l…

【pinia】Pinia入門和基本使用:

文章目錄 一、 什么是pinia二、 創建空Vue項目并安裝Pinia1. 創建空Vue項目2. 安裝Pinia并注冊 三、 實現counter四、 實現getters五、 異步action六、 storeToRefs保持響應式解構七、基本使用&#xff1a;【1】main.js【2】store》index.js【3】member.ts 一、 什么是pinia P…

Python:列表、元組、集合、字典,數據類型之間的 5 個差異

Python&#xff1a;列表、元組、集合、字典&#xff0c;數據類型之間的 5 個差異 1. 相同點2. 不同點2.1 排序2.2 索引2.3 可變性2.5 允許的類型2.4 允許重復 源碼 這篇博客將介紹列表、元組、集合、字典&#xff08;lists, tuples, sets, and dictionaries&#xff09;數據類型…

6.0 Python 使用函數裝飾器

裝飾器可以使函數執行前和執行后分別執行其他的附加功能&#xff0c;這種在代碼運行期間動態增加功能的方式&#xff0c;稱之為"裝飾器"(Decorator)&#xff0c;裝飾器的功能非常強大&#xff0c;裝飾器一般接受一個函數對象作為參數&#xff0c;以對其進行增強&…

安達發APS|生產計劃排產軟件助力加工制造業智能化轉型

隨著全球經濟一體化的不斷深入&#xff0c;市場競爭日益激烈&#xff0c;加工制造企業面臨著巨大的生存壓力。在這種情況下&#xff0c;企業對于生產計劃的精細化管理需求日益迫切。為了適應這一市場需求&#xff0c;安達發推出了專門針對加工企業的APS生產計劃排產軟件&#x…

新一代構建工具 maven-mvnd

新一代構建工具 maven-mvnd mvnd的前世今生下載安裝 mvndIDEA集成 mvnd的前世今生 maven 作為一代經典的構建工具&#xff0c;流行了很多年&#xff0c;知道現在依然是大部分Java項目的構建工具的首選&#xff1b;但隨著項目復雜度提高&#xff0c;代碼量及依賴庫的增多使得ma…

簡單易懂的 Postman Runner 參數自增教程

目錄 什么是 Postman Runner&#xff1f; Postman Runner 如何實現參數自增&#xff1f; 步驟一&#xff1a;設置全局參數 步驟二&#xff1a;將全局參數帶入請求參數 步驟三&#xff1a;實現參數自增 資料獲取方法 什么是 Postman Runner&#xff1f; Postman Runner 是…

Python爬蟲(1)一次性搞定Selenium(新版)8種find_element元素定位方式

selenium中有8種不錯的元素定位方式&#xff0c;每個方式和應用場景都不一樣&#xff0c;需要根據自己的使用情況來進行修改 8種find_element元素定位方式 1.id定位2.CSS定位3.XPATH定位4.name定位5.class_name定位6.Link_Text定位7.PARTIAL_LINK_TEXT定位8.TAG_NAME定位總結 …

【第一階段】kotlin中反引號中的函數名特點

在kotlin中可以直接中文定義函數&#xff0c;使用反引號進行調用 eg: fun main() {2023年8月9日定義的函數(5) }private fun 2023年8月9日定義的函數(num:Int){println("反引號的用法$num") }執行結果 在Java中is,in可以定義方法&#xff0c;但是在kotlin中is,in是…

資料分析(三)—— 基期、現期、人口、增長量

基期 基期值 現期值 - 增長量 增長量/增長率 現期值/1&#xff08;間隔)增長率 化除為乘 &#xff1a;當增長率&#xff5c;r| < 5% 時&#xff0c;&#xff0c; 注&#xff1a;當選項首位相同&#xff0c;第二位也相同時&#xff0c;只能用直除 基期和差 (結合選…

SolidUI社區-根據Prompt打造人設

背景 隨著文本生成圖像的語言模型興起&#xff0c;SolidUI想幫人們快速構建可視化工具&#xff0c;可視化內容包括2D,3D,3D場景&#xff0c;從而快速構三維數據演示場景。SolidUI 是一個創新的項目&#xff0c;旨在將自然語言處理&#xff08;NLP&#xff09;與計算機圖形學相…

【openwrt學習筆記】dnsmasq源碼閱讀

目錄 一、DHCP(Dynamic Host Configuration Protocol)1.1 前置知識1.2 參考鏈接1.3 IP地址分配代碼分析rfc2131.cdhcp-common.cdhcp.c 1.4 幾個小問題1.4.1 連續IP模式&#xff08;sequential_ip&#xff09;1.4.2 重新連接使用IP地址1.4.3 續約租期1.4.4 不同的MAC地址分配到相…

VS+Qt+C++旅游景區地圖導航源碼實例

程序示例精選 VSQtC旅游景區地圖導航 如需安裝運行環境或遠程調試&#xff0c;見文章底部個人QQ名片&#xff0c;由專業技術人員遠程協助&#xff01; 前言 這篇博客針對<<VSQtC旅游景區地圖導航>>編寫代碼&#xff0c;代碼整潔&#xff0c;規則&#xff0c;易讀。…

【Vue框架】菜單欄權限的使用與顯示

前言 在 【Vue框架】Vue路由配置 中的getters.js里&#xff0c;可以看到有一個應用程序的狀態&#xff08;變量&#xff09;叫 permission_routes&#xff0c;這個就是管理前端菜單欄的狀態。具體代碼的介紹&#xff0c;都以注釋的形式來說明。 1、modules\permission.js 1…