【STM32F407】第7章 ThreadX NetXDUO TCP傳輸控制協議基礎知識
最新教程下載:http://www.armbbs.cn/forum.php?mod=viewthread&tid=104619
第7章 ThreadX NetXDUO TCP傳輸控制協議基礎知識
本章節為大家講解TCP(Transmission Control Protocol,傳輸控制協議),通過本章節的學習,需要大家對TCP有個基本的認識,方便後面章節TCP實戰操作。
(本章的知識點主要整理自網路)
7.1 初學者重要提示
7.2 TCP基礎知識參考資料
7.3 TCP基礎知識點
7.4 TCP可靠性實現
7.5 TCP埠號
7.6 總結
7.1 初學者重要提示
1、 磨刀不誤砍柴工,初學者務必要對TCP的基礎知識點有個認識,不是特別理解沒有關係,隨著後面逐漸的實戰操作,會有比較全面的認識。
7.2 TCP基礎知識參考資料
首次搞TCP通訊,需要對TCP的一些基礎知識有個瞭解。大家可以從以下地址獲得TCP基礎知識:
- RFC793地址 : ftp://ftp.rfc-editor.org/in-notes/rfc793.txt 。
- wiki百科中文版:地址連結(這個是超連結)
- wiki百科英文版:地址連結(這個是超連結)
- 百度百科:地址連結(這個是超連結)
對於初學者來說,學習上面四個參考資料就夠了。如果大家有網路方面的書籍,比如《TCP/IP詳解》,也可以直接看書籍。
7.3 TCP基礎知識點
(這裡的知識點整理自上面的參考資料地址)
教程這裡也對TCP的基礎知識做個介紹,方便大家快速上手操作。
7.3.1 TCP簡要說明
TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議,由IETF的RFC 793定義。在簡化的計算機網路OSI模型中,它完成第四層傳輸層所指定的功能,使用者資料報協議UDP是同一層內另一個重要的傳輸協議。在因特網協議族中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連線,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。
應用層向TCP層傳送用於網間傳輸的資料流,然後TCP把資料流分成適當長度的報文段(受最大傳輸單元MTU的限制)。之後TCP把資料包傳給IP層,由它來通過網路將資料包傳送給接收端的TCP層。TCP為了保證不發生丟包,會給每個包一個序號,同時序號也保證了傳送到接收端時,資料包的按序接收。然後接收端對已成功收到的包發回一個應答(ACK),如果傳送端在設定的重傳時間內未收到應答,那麼對應的資料包會被認為已丟失將會進行重傳。TCP使用校驗和來檢驗資料是否有錯誤,在傳送和接收時都要計算校驗和。
7.3.2 TCP資料格式
- Source Port(源埠16bits)
傳送埠。
- Destination Port(目的埠16bits)
接收埠。
- Sequence Number(序列號32bits)
- 如果SYN標誌 = 1,那麼這是初始序列號。第一個資料的序列號為本序列號加1。
- 如果SYN標誌 = 0,那麼這是第一個資料的序列號。
- Acknowledgement Number(確認號32bits)
如果設定了ACK標誌,則該欄位的值是期望收到的資料的開始序列號,也即已經收到資料的位元組長度加1。
- Data Offset(報頭長度4bits)
以4位元組為單位計算出的資料段開始地址的偏移值。
- Reserved(保留)
必須置0。
- 標誌符
- URG(1bit)—為1表示高優先順序資料包,緊急指標欄位有效。
- ACK(1bit)—為1表示確認欄位有效。客戶端傳送的初始SYN包後的所有資料包都應該設定此標誌。
- PSH(1bit)—為1表示是帶有PUSH標誌的資料,指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿。
- RST(1bit)—為1表示出現嚴重差錯,可能需要重新建立TCP連線。還可以用於拒絕非法的報文段和拒絕連線請求。
- SYN(1bit)—為1表示這是連線請求或是連線接受請求,用於建立連線和使順序號同步。
- FIN(1bit)—為1表示傳送方沒有資料要傳輸了,要求釋放連線。
- Window(視窗16bits)
表示從確認號開始,本報文的源方可以接收的位元組數,即源方接收視窗大小,用於流量控制。
- Checksum(校驗和16bits)
對整個的TCP報文段,包括TCP頭部和TCP資料,以16bits為單位進行計算所得。這是一個強制性的欄位。
- Urgent Pointer(緊急指標16bits)
本報文段中緊急資料的最後一個位元組的序號。
- Options(選項欄位)
最多40位元組。每個選項的開始是1位元組的型別欄位,說明選項的型別。
-
- 0:選項表結束(1位元組)。
- 1:無操作(1位元組)用於選項欄位之間的字邊界對齊。
- 2:最大報文段長度(4位元組,Maximum Segment Size,MSS)通常在建立連線時設定SYN標誌的資料包中指明這個選項,指明本端所能接收的最大長度的報文段。通常將MSS設定為MTU 減去40位元組,攜帶TCP報文段的IP資料報的長度就不會超過MTU,從而避免本機發生IP分片。此選項只能出現在同步報文段中,否則將被忽略。
- 3:視窗擴大因子(4位元組,wscale),取值0-14。用來把TCP的視窗的值左移的位數。只能出現在同步報文段中,否則將被忽略。這是因為現在的TCP接收資料緩衝區(接收視窗)的長度通常大於65535位元組。
- 4:sackOK傳送端支援並同意使用SACK選項。
- 5:SACK實際工作的選項。
- 8:時間戳(10位元組,TCP Timestamps Option,TSopt)。
傳送端的時間戳(Timestamp Value field,TSval,4位元組)。
時間戳回顯應答(Timestamp Echo Reply field,TSecr,4位元組)。
- Padding(零填充)
TCP頭填充用於確保TCP頭資料是4位元組的整數倍,填充零。
- TCP Data(TCP資料段)
剩下就是TCP資料欄位了。
7.3.3 TCP建立連線
TCP使用三次握手協議建立連線。當主動方發出SYN連線請求後,等待對方回答SYN+ACK,並最終對對方的SYN執行ACK確認。這種建立連線的方法可以防止產生錯誤的連線,TCP使用的流量控制協議是可變大小的滑動視窗協議。TCP三次握手的過程如下:
- 客戶端傳送SYN(SEQ=x)報文給伺服器端,進入SYN_SEND狀態。
- 伺服器端收到SYN報文,迴應一個SYN(SEQ=y)+ ACK(ACK=x+1)報文,進入SYN_RECV狀態。
- 客戶端收到伺服器端的SYN報文,迴應一個ACK(ACK=y+1)報文,進入Established狀態。
三次握手完成,TCP客戶端和伺服器端成功地建立連線,可以開始傳輸資料了。
7.3.4 TCP資料傳輸
在TCP的資料傳送狀態,很多重要的機制保證了TCP的可靠性和強壯性。它們包括:
- 使用序號,對收到的TCP報文段進行排序以及檢測重複的資料。
- 使用校驗和來檢測報文段的錯誤。
- 使用確認和計時器來檢測和糾正丟包或延時。
在TCP的連線建立狀態,兩個主機的TCP層間要交換初始序號(ISN:initial sequence number)。這些序號用於標識位元組流中的資料,並且還是對應用層的資料位元組進行記數。通常在每個TCP報文段中都有一對序號和確認號。TCP報文傳送者認為自己的位元組編號為序號,而認為接收者的位元組編號為確認號。TCP報文的接收者為了確保可靠性,在接收到一定數量的連續位元組流後才傳送確認。這是對TCP的一種擴充套件,通常稱為選擇確認(Selective Acknowledgement)。選擇確認使得TCP接收者可以對亂序到達的資料塊進行確認。每一個位元組傳輸過後,ISN號都會遞增1。
通過使用序號和確認號,TCP層可以把收到的報文段中的位元組按正確的順序交付給應用層。序號是32位的無符號數,在它增大到2^32 - 1時,便會迴繞到0。對於ISN的選擇是TCP中關鍵的一個操作,它可以確保強壯性和安全性。
資料傳輸舉例:
- 傳送方首先發送第一個包含序列號為1(可變化)和1460位元組資料的TCP報文段給接收方。接收方以一個沒有資料的TCP報文段來回復(只含報頭),用確認號1461來表示已完全收到並請求下一個報文段。
- 傳送方然後傳送第二個包含序列號為1461和1460位元組資料的TCP報文段給接收方。正常情況下,接收方以一個沒有資料的TCP報文段來回復,用確認號2921(1461+1460)來表示已完全收到並請求下一個報文段。傳送接收這樣繼續下去。
- 然而當這些資料包都是相連的情況下,接收方沒有必要每一次都回應。比如,它收到第1到5條TCP報文段,只需迴應第五條就行了。在例子中第3條TCP報文段被丟失了,所以儘管它收到了第4和第5條,然而它只能迴應第2條。
- 傳送方在傳送了第3條以後,沒能收到迴應,因此當時鍾超時後,它重發第3條。(每次傳送者傳送一條TCP報文段後,都會再次啟動一次時鐘:RTT)。
- 這次第3條被成功接收,接收方可以直接確認第5條,因為4,5兩條已收到。
7.3.5 TCP終止連線
建立一個連線需要三次握手,而終止一個連線要經過四次握手,這是由TCP的半關閉(half-close)造成的。具體過程如下圖所示。
- 某個應用程序首先呼叫close,稱該端執行“主動關閉”(active close)。於是該端的TCP傳送一個FIN分節,表示資料傳送完畢。
- 接收到這個FIN的對端執行 “被動關閉”(passive close),這個FIN由TCP確認。
注意:FIN的接收也作為一個檔案結束符(end-of-file)傳遞給接收端應用程序,放在已排隊等候該應用程序接收的任何其他資料之後,因為,FIN的接收意味著接收端應用程序在相應連線上再無額外資料可接收。
- 一段時間後,接收到這個檔案結束符的應用程序將呼叫close關閉它的套接字。這導致它的TCP也傳送一個FIN。
- 接收這個最終FIN的原發送端TCP(即執行主動關閉的那一端)確認這個FIN。
既然每個方向都需要一個FIN和一個ACK,因此通常需要4個分節。
注意:
- “通常”是指,某些情況下,步驟1的FIN隨資料一起傳送,另外,步驟2和步驟3傳送的分節都出自執行被動關閉那一端,有可能被合併成一個分節。
- 在步驟2與步驟3之間,從執行被動關閉一端到執行主動關閉一端流動資料是可能的,這稱為“半關閉”(half-close)。
- 當一個Unix程序無論自願地(呼叫exit或從main函式返回)還是非自願地(收到一個終止本程序的訊號)終止時,所有開啟的描述符都被關閉,這也導致仍然開啟的任何TCP連線上也發出一個FIN。
無論是客戶還是伺服器,任何一端都可以執行主動關閉。通常情況是,客戶執行主動關閉,但是某些協議,例如,HTTP/1.0卻由伺服器執行主動關閉。
7.3.6 TCP校驗和
TCP的16位校驗和(checksum)的計算和檢驗過程如下:傳送者將TCP報文段的頭部和資料部分的和計算出來,再對其求反碼(一的補數),就得到了校驗和,然後將結果裝入報文中傳輸。(這裡用反碼的原因是這種方法的迴圈進位使校驗和可以在16位、32位、64位等情況下的計算結果再疊加後相同。)接收者在收到報文後再按相同的演算法計算一次校驗和。這裡使用的反碼使得接收者不用再將校驗和欄位儲存起來後清零,而可以直接將報文段連同校驗加總。如果計算結果是全部為一,那麼就表示了報文的完整性和正確性。
注意:TCP校驗和也包括了96位的偽頭部,其中有源地址、目的地址、協議以及TCP的長度。這可以避免報文被錯誤地路由。
7.4 TCP可靠性實現
7.4.1 可靠性
TCP提供一種面向連線的、可靠的位元組流服務。面向連線意味著兩個使用TCP的應用(通常是一個客戶和一個伺服器)在彼此交換資料包之前必須先建立一個TCP連線。這一過程與打電話很相似,先撥號振鈴,等待對方摘機說“喂”,然後才說明是誰。在一個TCP連線中,僅有兩方進行彼此通訊。廣播和多播不能用於TCP。
TCP通過下列方式來提供可靠性:
- 應用資料被分割成TCP認為最適合傳送的資料塊。這和UDP完全不同,應用程式產生的資料長度將保持不變。由TCP傳遞給IP的資訊單位稱為報文段或段(segment)。
- 當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。當TCP收到發自TCP連線另一端的資料,它將傳送一個確認。TCP有延遲確認的功能,在此功能沒有開啟,則是立即確認。功能開啟,則由定時器觸發確認時間點。
- TCP將保持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的校驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。
- 既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層。
- 既然IP資料報會發生重複,TCP的接收端必須丟棄重複的資料。
- TCP還能提供流量控制。TCP連線的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的緩衝區溢位。
兩個應用程式通過TCP連線交換8bit位元組構成的位元組流。TCP不在位元組流中插入記錄識別符號。我們將這稱為位元組流服務(bytestreamservice)。如果一方的應用程式先傳10位元組,又傳20位元組,再傳50位元組,連線的另一方將無法瞭解傳送方每次傳送了多少位元組。只要自己的接收快取沒有塞滿,TCP 接收方將有多少就收多少。一端將位元組流放到TCP連線上,同樣的位元組流將出現在TCP連線的另一端。
另外,TCP對位元組流的內容不作任何解釋。TCP不知道傳輸的資料位元組流是二進位制資料,還是ASSⅡ字元或者其他型別資料。對位元組流的解釋由TCP連線雙方的應用層解釋。
7.4.2 重傳策略
TCP協議用於控制資料段是否需要重傳的依據是設立重發定時器。在傳送一個數據段的同時啟動一個重傳,如果在重傳超時前收到確認(Acknowlegement)就關閉該重傳,如果重傳超時前沒有收到確認,則重傳該資料段。在選擇重發時間的過程中,TCP必須具有自適應性。它需要根據網際網路當時的通訊情況,給出合適的重發時間。
這種重傳策略的關鍵是對定時器初值的設定。採用較多的演算法是Jacobson於1988年提出的一種不斷調整超時時間間隔的動態演算法。其工作原理是對每條連線TCP都保持一個變數RTT(Round Trip Time),用於存放當前到目的端往返所需要時間最接近的估計值。當傳送一個數據段時,同時啟動連線的定時器,如果在定時器超時前確認到達,則記錄所需要的時間,並修正RTT的值,如果定時器超時前沒有收到確認,則將RTT的值增加1倍。通過測量一系列的RTT值,TCP協議可以估算資料包重發前需要等待的時間。在估計該連線所需的當前延遲時通常利用一些統計學的原理和演算法(如Karn演算法),從而得到TCP重發之前需要等待的時間值。
7.4.3 視窗確認
TCP的一項功能就是確保每個資料段都能到達目的地。位於目的主機的TCP服務對接受到的資料進行確認,並向源應用程式傳送確認資訊。
使用資料報頭序列號以及確認號來確認已收到包含在資料段的相關資料。
TCP在發回源裝置的資料段中使用確認號,指示接收裝置期待接收的下一位元組。這個過程稱為期待確認。源主機在收到確認訊息之前可以傳輸的資料大小稱為視窗大小,用於管理丟失資料和流量控制。
如下圖所示(來自wiki)。
7.4.4 配置TCP
- 修改建立TCP連線的超時時間
建立TCP連線需要經過三次握手:主動端先發送SYN報文,被動端迴應SYN+ACK報文,然後主動端再回應ACK。
在主動端傳送SYN後,如果被動端一直不迴應SYN+ACK報文,主動端會不斷的重傳SYN報文直到超過一定的重傳次數或超時時間。
在主動端傳送SYN後,被動端迴應SYN+ACK報文,但主動端不再回復ACK,被動端也會一直重傳直到超過一定的重傳次數或超時時間。(SYN報文攻擊會出現這種情況)
因此,使用者可以配置SYN報文的超時時間(傳送SYN報文到三次握手成功的最大時間),也就是建立TCP連線的超時時間,來達到更好的連線效果。
- 修改緩衝區大小
TCP的接收緩衝區是用來快取從對端接收到的資料,這些資料後續會被應用程式讀取。一般情況下,TCP報文的視窗值反映接收緩衝區的空閒空間的大小。對於頻寬比較大、有大批量資料的連線,增大接收緩衝區的大小可以顯著提供TCP傳輸效能。TCP的傳送緩衝區是用來快取應用程式的資料,傳送緩衝區的每個位元組都有序列號,被應答確認的序列號對應的資料會從傳送緩衝區刪除掉。增大發送緩衝區可以提高TCP與應用程式的互動能力。但是增大接收和傳送緩衝區會導致TCP佔用比較多的記憶體。
7.5 TCP埠號
如果把IP地址比作一間房子 ,埠就是出入這間房子的門。真正的房子只有幾個門,但是一個IP地址的埠可以有65536(即:2^16)個之多!埠是通過埠號來標記的,埠號只有整數,範圍是從0 到65535(2^16-1)。
在Internet上,各主機間通過TCP/IP協議傳送和接收資料包,各個資料包根據其目的主機的IP地址來進行網際網路絡中的路由選擇,把資料包順利地傳送到目的主機。大多數作業系統都支援多程式(程序)同時執行,那麼目的主機應該把接收到的資料包傳送給眾多同時執行的程序中的哪一個呢?顯然這個問題有待解決,埠機制便由此被引入進來。
7.5.1 埠分類
按照埠號的大小分類,可分為如下幾類:
- 公認埠(WellKnown Ports):
公認埠是眾所周知的埠號,範圍從0到1023,其中80埠分配給WWW服務,21埠分配給FTP服務等。我們在IE的位址列裡輸入一個網址的時候是不必指定埠號的,因為在預設情況下WWW服務的埠是80。
網路服務是可以使用其他埠號的,如果不是預設的埠號則應該在位址列上指定埠號,方法是在地址後面加上冒號”:”(半形),再加上埠號。比如使用8080作為WWW服務的埠,則需要在位址列裡輸入“網址:8080”。
但是有些系統協議使用固定的埠號,它是不能被改變的,比如139 埠專門用於NetBIOS與TCP/IP之間的通訊,不能手動改變。
- 註冊埠(Registered Ports):
埠1024到49151,分配給使用者程序或應用程式。這些程序主要是使用者選擇安裝的一些應用程式,而不是已經分配好了公認埠的常用程式。這些埠在沒有被伺服器資源佔用的時候,可以被使用者端動態選用為源埠。
- 動態埠(Dynamic Ports):
動態埠的範圍是從49152到65535。之所以稱為動態埠,是因為它一般不固定分配某種服務,而是動態分配。
具體到埠的實際分配情況,可以看如下兩個地址:
7.5.2 埠作用
我們知道,一臺擁有IP地址的主機可以提供許多服務,比如Web服務、FTP服務、SMTP服務等,這些服務完全可以通過1個IP地址來實現。那麼,主機是怎樣區分不同的網路服務呢?顯然不能只靠IP地址,因為IP 地址與網路服務的關係是一對多的關係。實際上是通過“IP地址+埠號”來區分不同的服務的。需要注意的是,埠並不是一 一對應的。比如你的電腦作為客戶機訪問一臺WWW伺服器時,WWW伺服器使用80埠與你的電腦通訊,但你的電腦則可能使用“3457”這樣的埠。
7.6 總結
本章節就為大家講解這麼多,更多TCP的相關知識需要大家查閱相關書籍進行學習,或者網上搜索相關資料進行學習。
微信公眾號:armfly_com 安富萊論壇:www.armbbs.cn 安富萊淘寶:https://armfly.taobao.com