# 網絡基本功(九):細說TCP重傳
**轉載請在文首保留原文出處:EMC中文支持論壇**[https://community.emc.com/go/chinese](https://community.emc.com/go/chinese) [](http://service.weibo.com/share/share.php?title=%23ECN%e4%b8%ad%e6%96%87%e6%94%af%e6%8c%81%e8%ae%ba%e5%9d%9b%23 %e7%bd%91%e7%bb%9c%e5%9f%ba%e6%9c%ac%e5%8a%9f%ef%bc%88%e4%b9%9d%ef%bc%89%ef%bc%9a%e7%bb%86%e8%af%b4TCP%e9%87%8d%e4%bc%a0%ef%bc%88%e4%b8%8a%ef%bc%89@EMC%e6%98%93%e5%ae%89%e4%bf%a1%e4%b8%ad%e5%9b%bd%e6%8a%80%e6%9c%af%e7%a4%be%e5%8c%ba&url=https://community.emc.com/message/842129#842129)
## 介紹
TCP的主要任務是很簡單:打包和發送數據。TCP與其他協議的不同之處在于使用滑動窗口來管理基本數據收發過程,同時確保數據流的有效及可靠傳輸,從而不致發送速率明顯快于接收速率。本文將描述TCP是如何確保設備可靠、有效地進行傳輸的。首先闡述TCP檢測丟失片段以及重傳的基本方法,之后介紹TCP如何判斷一個片段為丟失片段。
## 更多信息
**TCP片段重傳計時器以及重傳隊列:**
檢測丟失片段并對之重傳的方法概念上是很簡單的。每一次發送一個片段,就開啟一個**重傳計時器**。計時器有一個初始值并隨時間遞減。如果在片段接收到確認之前計時器超時,就重傳片段。TCP使用了這一基本技術,但實現方式稍有不同。原因在于為了提高效率需要一次處理多個未被確認的片段,以保證每一個在恰當的時間重傳。TCP按照以下特定順序工作:
**放置于重傳隊列中,計時器開始** 包含數據的片段一經發送,片段的一份復制就放在名為**重傳隊列**的數據結構中,此時啟動重傳計時器。因此,在某些時間點,每一個片段都會放在隊列里。隊列按照重傳計時器的剩余時間來排列,因此TCP軟件可追蹤那幾個計時器在最短時間內超時。
**確認處理** 如果在計時器超時之前收到了確認信息,則該片段從重傳隊列中移除。
**重傳超時** 如果在計時器超時之前沒有收到確認信息,則發生重傳超時,片段自動重傳。當然,相比于原片段,對于重傳片段并沒有更多的保障機制。因此,重傳之后該片段還是保留在重傳隊列里。重傳計時器被重啟,重新開始倒計時。如果重傳之后沒有收到確認,則片段會再次重傳并重復這一過程。在某些情況下重傳也會失敗。我們不想要TCP永遠重傳下去,因此TCP只會重傳一定數量的次數,并判斷出現故障終止連接。
但是我們怎樣知道一個片段被完全確認呢?重傳是基于片段的,而TCP確認信息是基于序列號累積的。每次當設備A發送片段給設備B,設備B查看該片段的確認號字段。所有低于該字段的序列號都已經被設備A接收了。因此,當片段中所發送的所有字節的序列號都比設備A到設備B的最后一個確認號小的時候,一個從設備B發到設備A的片段被認為是確認了。這是通過計算片段中最后一個序列號結合片段的數據字段來實現的。
讓我們以下圖為例來說明一下確認和重傳是怎樣工作的。假設連接中的服務器發出了四個連續片段(號碼從1開始)
**片段1** 序列號字段是1片段長度80。所以片段1中最后一個序列號是80。
**片段2** 序列號是81片段長度是120。片段2中最后一個序列號是200。
**片段3** 序列號是201片段長度是160。片段3中最后一個序列號是360。
**片段4** 序列號是361片段長度是140。片段3中最后一個序列號是500。
這些片段是一個接一個發送的,而無需等待前一個發送得到確認。這是TCP滑動窗口的一個主要優勢([細說TCP滑動窗口](https://community.emc.com/message/840427#840427))。
假設客戶端接收到前兩個傳輸,它會發回一條確認消息確認號為201。從而告知服務器前兩個片段已經被客戶端成功接收了,它們從重傳隊列中移除(并且服務器發送窗口右移200字節)。在接收到確認號361或更高的片段之前,片段3會保留在重傳隊列中;片段4需要確認號501或更高。
現在,讓我們進一步假設傳輸過程中片段3丟失了,但片段4被接收到了。客戶端將片段4保存在接收buffer中,但是不需要確認,因為TCP是累積確認機制——確認片段4表示片段3也接收到了,但實際上并沒有。因此,客戶端需要等待片段3。實際上,服務器端片段3的重傳計時器會超時,服務器之后重傳片段3。之后客戶端收到,然后發送片段3和4的確認信息給服務器。
還有一個重要的問題,服務器將如何處理片段4呢?雖然客戶端在等待片段3,服務器沒有收到反饋,所以它并不知道片段3丟失了,同樣它也不知道片段4發生了什么(以及接下來傳輸的數據)。很有可能客戶端已經接收到了片段4但是不能確認,也有可能片段4也丟失了。一些實現中會選擇僅僅重傳片段3,也有些會把3和4都重傳。
[](https://community.emc.com/servlet/JiveServlet/showImage/2-842129-96705/image002.jpg)
最后一個問題是重傳隊列中所使用片段重傳計時器的值。如果設置過低,會發生過量重傳,如果設置過高,重傳丟失片段會減弱性能。必須通過一個稱為自適應重傳的過程來動態調整這個值,接下來的章節會講到。
- 介紹
- 網絡基本功(一):細說網絡傳輸
- 網絡基本功(二):細說交換機
- 網絡基本功(三):細說VLAN與Trunk
- 網絡基本功(四):細說路由(上)
- 網絡基本功(五):細說路由(下)
- 網絡基本功(六):鏈路聚合
- 網絡基本功(七):細說IP地址與子網
- 網絡基本功(八):細說TCP滑動窗口
- 網絡基本功(九):細說TCP重傳
- 網絡基本功(十):細說TCP確認機制
- 網絡基本功(十一):TCP窗口調整與流控
- 網絡基本功(十二):細說Linux網絡配置(上)
- 網絡基本功(十三):細說Linux網絡配置(下)
- 網絡基本功(十四):細說診斷工具ping
- 網絡基本功(十五):細說網絡性能監測與實例(上)
- 網絡基本功(十六):細說網絡性能監測與實例(下)
- 網絡基本功(十七):細說tcpdump的妙用(上)
- 網絡基本功(十八):細說tcpdump的妙用(下)
- 網絡基本功(十九):細說NAT原理與配置
- 網絡基本功(二十):細說ICMP和ARP
- 網絡基本功(二十一):細說HTTP(上)
- 網絡基本功(二十二):細說HTTP(下)
- 網絡基本功(二十三):Wireshark抓包實例診斷TCP連接問題
- 網絡基本功(二十四):Wireshark抓包實例分析TCP重傳
- 網絡基本功(二十五):Wireshark抓包實例分析TCP重復ACK與亂序
- 網絡基本功(二十六):Wireshark抓包實例分析TCP窗口及reset
- 網絡基本功(二十七):Wireshark抓包實例分析HTTP問題(上)
- 網絡基本功(二十八):Wireshark抓包實例分析HTTP問題(下)
- 網絡基本功(二十九):Wireshark抓包實例診斷數據庫常見問題
- 網絡基本功(三十):細說DNS(上)
- 網絡基本功(三十一):細說DHCP