TCP協議-如何保證傳輸可靠性

TCP協議傳輸的特點主要就是面向字節流、傳輸可靠、面向連接。這篇博客,我們就重點討論一下TCP協議如何確保傳輸的可靠性的。

確保傳輸可靠性的方式

TCP協議保證數據傳輸可靠性的方式主要有:

  • 校驗和
  • 序列號
  • 確認應答
  • 超時重傳
  • 連接管理
  • 流量控制
  • 擁塞控制

校驗和

計算方式:在數據傳輸的過程中,將發送的數據段都當做一個16位的整數。將這些整數加起來。并且前面的進位不能丟棄,補在后面,最后取反,得到校驗和。?
發送方:在發送數據之前計算檢驗和,并進行校驗和的填充。?
接收方:收到數據后,對數據以同樣的方式進行計算,求出校驗和,與發送方的進行比對。

注意:如果接收方比對校驗和與發送方不一致,那么數據一定傳輸有誤。但是如果接收方比對校驗和與發送方一致,數據不一定傳輸成功。(校驗和保證的是數據的正確性,下面介紹的機制是保證數據能夠被成功接收)

確認應答與序列號?

序列號:TCP傳輸時將每個字節的數據都進行了編號,這就是序列號。?
確認應答:TCP傳輸的過程中,每次接收方收到數據后,都會對傳輸方進行確認應答。也就是發送ACK報文。這個ACK報文當中帶有對應的確認序列號,告訴發送方,接收到了哪些數據,下一次的數據從哪里發。

序列號的作用不僅僅是應答的作用,有了序列號能夠將接收到的數據根據序列號排序,并且去掉重復序列號的數據。這也是TCP傳輸可靠性的保證之一。

超時重傳

在進行TCP傳輸時,由于確認應答與序列號機制,也就是說發送方發送一部分數據后,都會等待接收方發送的ACK報文,并解析ACK報文,判斷數據是否傳輸成功。如果發送方發送完數據后,遲遲沒有等到接收方的ACK報文,這該怎么辦呢?而沒有收到ACK報文的原因可能是什么呢?

首先,發送方沒有接收到響應的ACK報文原因可能有兩點:

  1. 數據在傳輸過程中由于網絡原因等直接全體丟包,接收方根本沒有接收到。
  2. 接收方接收到了響應的數據,但是發送的ACK報文響應卻由于網絡原因丟包了。

TCP在解決這個問題的時候引入了一個新的機制,叫做超時重傳機制。簡單理解就是發送方在發送完數據后等待一個時間,時間到達沒有接收到ACK報文,那么對剛才發送的數據進行重新發送。如果是剛才第一個原因,接收方收到二次重發的數據后,便進行ACK應答。如果是第二個原因,接收方發現接收的數據已存在(判斷存在的根據就是序列號,所以上面說序列號還有去除重復數據的作用),那么直接丟棄,仍舊發送ACK應答。

那么發送方發送完畢后等待的時間是多少呢?如果這個等待的時間過長,那么會影響TCP傳輸的整體效率,如果等待時間過短,又會導致頻繁的發送重復的包。如何權衡?

由于TCP傳輸時保證能夠在任何環境下都有一個高性能的通信,因此這個最大超時時間(也就是等待的時間)是動態計算的。
?

在Linux中(BSD Unix和Windows下也是這樣)超時以500ms為一個單位進行控制,每次判定超時重發的超時時間
都是500ms的整數倍。重發一次后,仍未響應,那么等待2*500ms的時間后,再次重傳。等待4*500ms的時間繼續
重傳。以一個指數的形式增長。累計到一定的重傳次數,TCP就認為網絡或者對端出現異常,強制關閉連接。

連接管理

連接管理就是三次握手與四次揮手的過程,在前面詳細講過這個過程,這里不再贅述。保證可靠的連接,是保證可靠性的前提。

流量控制

接收端在接收到數據后,對其進行處理。如果發送端的發送速度太快,導致接收端的結束緩沖區很快的填充滿了。此時如果發送端仍舊發送數據,那么接下來發送的數據都會丟包,繼而導致丟包的一系列連鎖反應,超時重傳呀什么的。而TCP根據接收端對數據的處理能力,決定發送端的發送速度,這個機制就是流量控制。

在TCP協議的報頭信息當中,有一個16位字段的窗口(接收端反饋窗口)大小。在介紹這個窗口大小時我們知道,窗口大小的內容實際上是接收端接收數據緩沖區的剩余大小。這個數字越大,證明接收端接收緩沖區的剩余空間越大,網絡的吞吐量越大。接收端會在確認應答發送ACK報文時,將自己的即時窗口大小填入,并跟隨ACK報文一起發送過去。而發送方根據ACK報文里的窗口大小的值的改變進而改變自己的發送速度。如果接收到窗口大小的值為0,那么發送方將停止發送數據。并定期的向接收端發送窗口探測數據段,讓接收端把窗口大小告訴發送端。?

注:16位的窗口大小最大能表示65535個字節(64K),但是TCP的窗口大小最大并不是64K。在TCP首部中40個字節的選項中還包含了一個窗口擴大因子M,實際的窗口大小就是16為窗口字段的值左移M位。每移一位,擴大兩倍。

擁塞控制

TCP傳輸的過程中,發送端開始發送數據的時候,如果剛開始就發送大量的數據,那么就可能造成一些問題。網絡可能在開始的時候就很擁堵,如果給網絡中在扔出大量數據,那么這個擁堵就會加劇。擁堵的加劇就會產生大量的丟包,就對大量的超時重傳,嚴重影響傳輸。

所以TCP引入了慢啟動的機制,在開始發送數據時,先發送少量的數據探路。探清當前的網絡狀態如何,再決定多大的速度進行傳輸。這時候就引入一個叫做擁塞窗口的概念。發送剛開始定義擁塞窗口為 1,每次收到ACK應答,擁塞窗口加 1(加一位翻一倍)。在發送數據之前,首先將擁塞窗口與接收端反饋的窗口大小比對,取較小的值作為實際發送的窗口。

擁塞窗口的增長是指數級別的。慢啟動的機制只是說明在開始的時候發送的少,發送的慢,但是增長的速度是非常快的。為了控制擁塞窗口的增長,不能使擁塞窗口單純的加倍,設置一個擁塞窗口的閾值,當擁塞窗口大小超過閾值時,不能再按照指數來增長,而是線性的增長。在慢啟動開始的時候,慢啟動的閾值等于窗口的最大值,一旦造成網絡擁塞,發生超時重傳時,慢啟動的閾值會為原來的一半(這里的原來指的是發生網絡擁塞時擁塞窗口的大小),同時擁塞窗口重置為 1。?

擁塞控制是TCP在傳輸時盡可能快的將數據傳輸,并且避免擁塞造成的一系列問題。是可靠性的保證,同時也是維護了傳輸的高效性。

原文地址:https://blog.csdn.net/liuchenxia8/article/details/80428157

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

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

相關文章

TCP協議-握手與揮手

認識TCP協議 TCP全稱為“傳輸控制協議”,這是傳輸層的一個協議,對數據的傳輸進行一個詳細的控制。 特點: 面向字節流安全可靠面向連接 TCP協議段格式 源端口號與目的端口號:這里與UDP的一樣,每個數據都要知道從哪個…

ASOC注冊過程

一、什么是ASOC 在嵌入式系統里面的聲卡驅動為ASOC(ALSA System on Chip) ,它是在ALSA 驅動程序上封裝的一層,分為3大部分,Machine,Platform和Codec ,三部分的關系如下圖所示:其中Machine是指我…

ASOC調用過程

上一篇文章我們將了嵌入式系統注冊聲卡的過程:https://blog.csdn.net/qq_37659294/article/details/104748747 這篇文章我們以打開一個聲卡的播放節點為例,講解一下在APP調用open時,最終會如何調用到硬件相關的函數。 在上一篇文章最后我們說…

編寫聲卡驅動(框架)

在前面兩篇文章中,我們分別講了嵌入式Linux系統聲卡注冊的過程和調用的過程: https://blog.csdn.net/qq_37659294/article/details/104748747 https://blog.csdn.net/qq_37659294/article/details/104802868 講了那么多,我們最終的目的無非…

聲卡學習筆記

分享幾篇關于韋東山聲卡驅動的學習筆記,作者寫得非常詳細。 ALSA驅動框架:https://blog.csdn.net/qingkongyeyue/article/details/52328991 ASoC驅動框架:https://blog.csdn.net/qingkongyeyue/article/details/52349120 ASoC驅動重要結構…

路由器、交換機、集線器的區別

https://blog.csdn.net/weibo1230123/article/details/82779040

$PATH環境變量的作用

echo $PATH 顯示當前PATH環境變量,該變量的值由一系列以冒號分隔的目錄名組成,如:/usr/local/bin:/bin:/usr/bin。(冒號:是路徑分隔符) 在執行一個程序的時候如果沒有PATH的話,就需要寫出路徑名(絕對或者相對&#xf…

dmesg

https://blog.csdn.net/zm_21/article/details/31760569

進程上下文與中斷上下文的理解

一.什么是內核態和用戶態 內核態:在內核空間執行,通常是驅動程序,中斷相關程序,內核調度程序,內存管理及其操作程序。 用戶態:用戶程序運行空間。 二.什么是進程上下文與中斷上下文 1.進程上下文&#xf…

GDB調試教程:1小時玩轉Linux gdb命令

原文鏈接&#xff1a;http://c.biancheng.net/gdb/ GDB 入門教程 本教程以下面的代碼為例&#xff0c;在 Linux 系統下來講解 GBD 的調試流程&#xff1a; int main (void) {unsigned long long int n, sum;n 1;sum 0;while (n < 100){sum sum n;n n 1;}return 0; …

shell將命令執行的結果賦值給 變量

https://blog.csdn.net/lemontree1945/article/details/79126819/

Linux下shell腳本指定程序運行時長

https://www.cnblogs.com/yychuyu/p/12626798.html

vim編輯器如何刪除一行或者多行內容

http://blog.itpub.net/69955379/viewspace-2681334/

C++經典問題:如果對象A中有對象成員B,對象B沒有默認構造函數,那么對象A必須在初始化列表中初始化對象B?

對象成員特點總結&#xff1a; &#xff08;1&#xff09;實例化對象A時&#xff0c;如果對象A有對象成員B,那么先執行對象B的構造函數&#xff0c;再執行A的構造函數。 &#xff08;2&#xff09;如果對象A中有對象成員B,那么銷毀對象A時&#xff0c;先執行對象A的析構函數&…

JZ2440用U-Boot給Nand-Flash燒寫程序時報錯:NAND write: incorrect device type in bootloader ‘bootloader‘ is not

JZ2440開發板使用問題&#xff0c;U-Boot燒寫程序到Nand Flash時報錯&#xff1a;NAND write: incorrect device type in bootloader bootloader is not a number 這是因為分區名中u-boot&#xff0c;不是bootloader&#xff0c;而cmd_menu.c里用的是bootloader 可以執行&#…

韋東山銜接班——4.4_構建根文件系統之構建根文件系統

文章地址&#xff1a; https://blog.csdn.net/gongweidi/article/details/100086289?biz_id102&utm_term%E9%9F%A6%E4%B8%9C%E5%B1%B1%E8%A1%94%E6%8E%A5%E7%8F%AD&utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~sobaiduweb~default-5-100086289&…

C++中const char *p和char const *p

const char *p;他的意思是p指向的目標空間的內容不可變化 例如定義char cA; p&c;則c的內容不可以變化.如cB;等一些企圖改變變量c的值的做法都不行. 然而p仍然是動態的,就是它還可以指向別的空間,被賦予新的地址值,只是被他指向的目標空間的內容不可變化,如上面的c值始終為A…

qt 分割字符串的兩種方法

https://blog.csdn.net/a724699769/article/details/62216435

【YOLO系列】YOLOv3代碼詳解(五):utils.py腳本

前言 以下內容僅為個人在學習人工智能中所記錄的筆記&#xff0c;先將目標識別算法yolo系列的整理出來分享給大家&#xff0c;供大家學習參考。 本文僅對YOLOV3代碼中關鍵部分進行了注釋&#xff0c;未掌握基礎代碼的鐵汁可以自己百度一下。 若文中內容有誤&#xff0c;希望大家…

內核的Makefile與Kconfig關系解析

在子目錄下的Kconfig里添加make menuconfig的選項&#xff08;如圖一&#xff09;&#xff0c;并默認設置為y&#xff0c;make menuconfig的菜單里就會有該項并默認為選上狀態&#xff0c;make menuconfig配置完之后在.config文件里就有該選項&#xff0c;并等于y&#xff08;如…