本文主要整理TCP協議的知識點算法
儘管TCP和UDP都使用相同的網絡層(IP), TCP卻嚮應用層提供與UDP徹底不一樣的服務。TCP提供一種面向鏈接的、可靠的字節流服務。緩存
TCP具備如下特色安全
一、面向鏈接 每一個TCP段都包含一個源端口號和目的端口號,用來肯定發送端和接收端的應用進程,而後結合IP首部中的源端IP地址和目的端IP地址就能惟一肯定一個TCP鏈接。網絡
二、可靠 TCP協議擁有各類機制來確保數據傳送的可靠性,例如超時重傳策略,保持首部和數據的校驗和,流量控制和校驗已收到數據的完整性和正確性等。併發
TCP報文段被封裝到IP數據報中,一般是20個字節。函數
源端口號和目的端口號:用於尋找發送端和接收端的應用進程,分別是16位性能
Sequence Number(序列號):報文段中的第一個字節,用於標識發送的數據字節流大數據
Acknowledgment Number(確認號):確認序列號包含發送確認的一端所指望收到的下一個序號,所以,確認序號應當是上次已成功收到數據字節序號加1。不過,只有當標誌位中的ACK標誌爲1時該確認序列號的字段纔有效。指針
Offset(數據偏移):給出首部中32 bit字的數目,須要這個值是由於任選字段的長度是可變的。這個字段佔4bit(最多能表示15個32bit的的字,即4*15=60個字節的首部長度),所以TCP最多有60字節的首部。然而,沒有任選字段,正常的長度是20字節;cdn
TCP Flags:TCP首部中有6個標誌比特,它們中的多個可同時被設置爲1,主要是用於操控TCP的狀態機的,依次爲URG,ACK,PSH,RST,SYN,FIN。每一個標誌位的意思以下:
URG:此標誌表示TCP包的緊急指針域有效,用來保證TCP鏈接不被中斷,而且督促中間層設備要儘快處理這些數據;
ACK:此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP數據包中;有兩個取值:0和1,爲1的時候表示應答域有效,反之爲0;
PSH:這個標誌位表示Push操做。該標誌通知接收方將接收到的數據所有提交給接收進程。這裏所說的數據包括與此PUSH包一塊兒傳輸的數據以及以前就爲該進程傳輸過來的數據。
RST:這個標誌表示鏈接復位請求。用來複位那些產生錯誤的鏈接,也被用來拒絕錯誤和非法的數據包;
SYN:表示同步序號,用來創建鏈接。SYN標誌位和ACK標誌位搭配使用,當鏈接請求的時候,SYN=1,ACK=0;鏈接被響應的時候,SYN=1,ACK=1;這個標誌的數據包常常被用來進行端口掃描。掃描者發送一個只有SYN的數據包,若是對方主機響應了一個數據包回來 ,就代表這臺主機存在這個端口;可是因爲這種掃描方式只是進行TCP三次握手的第一次握手,所以這種掃描的成功表示被掃描的機器不很安全,一臺安全的主機將會強制要求一個鏈接嚴格的進行TCP的三次握手;
FIN:用來結束一個TCP回話.但對應端口仍處於開放狀態,準備接收後續數據。
Window(窗口大小):窗口大小,也就是有名的滑動窗口,用來進行流量控制。
CheckSum(校驗和):檢驗和是一個強制性字段,是由發送端計算和保存,而後由接收端進行校驗
Urgent Pointer(緊急指針):只有當URG標誌置1時緊急指針纔有效。緊急指針是一個正的偏移量,和序號字段中的值相加表示緊急數據最後一個字節的序號。TCP的緊急方式是發送端向另外一端發送緊急數據的一種方式。
TCP數據部分是可選的,在創建和終止鏈接等狀況下就會發送不帶數據部分的報文段
TCP是一個面向鏈接的協議,一方向另外一方發送數據,必須先在雙方之間創建一條鏈接。
TCP鏈接的創建---三次握手
(1)客戶端執行主動打開操做,向服務端發送SYN報文,指明打算鏈接的服務端的端口,以及初始序號(ISN),而後進入SYN_SENT狀態。其中ISN隨時間而變化,因此不一樣的鏈接都將具備不一樣的ISN。
(2)服務端收到SYN報文後,一樣向客戶端發回一個帶有本身初始序號的SYN報文段,同時將ACK字段設爲客戶端ISN+1的值,做爲對客戶端SYN報文的確認響應,而後本身進入SYN_RCVD狀態。
(3)客戶端一樣將ACK字段設爲服務端ISN+1的值,做爲對服務端SYN報文的確認響應,本身進入ESTABLISHED狀態,服務端收到客戶端的確認響應後,也進入ESTABLISHED狀態。
鏈接創建成功後,雙方則可以發送數據,接收方則發送ACK報文做爲確認響應。
TCP鏈接的斷開---四次揮手
創建鏈接須要三次交互,而斷開鏈接則須要四次交互,這是因爲TCP鏈接是一個全雙工鏈接,須要雙方單獨來進行關閉,收到FIN報文意味着在這個方向上沒有數據流動,可是仍然能夠發送數據。
(1)應用關閉,須要斷開TCP鏈接,則向服務端發送FIN報文,並進入FIN_WAIT_1狀態;
(2)服務端收到客戶端發送的FIN請求,則回發ACK,ACK序列號爲ACK加1,進入CLOSE_WAIT狀態;客戶端收到ACK確認迴應後,進入FIN_WAIT_2狀態。此時,客戶端沒法發送數據,可是仍可接收服務端發來的數據,這種狀態稱爲半關閉狀態。
(3)服務端不須要發送數據時,則向客戶端發送FIN請求斷開鏈接,進入LAST_ACK狀態,客戶端收到斷開請求,迴應ACK,進入TIME_WAIT狀態;服務端收到ACK後,進入CLOSED,今後TCP鏈接成功斷開。
TCP所謂的「鏈接」,實際上是通信雙方維護的一種狀態,看上去像是鏈接同樣,這就涉及到TCP鏈接過程當中,通信雙方不一樣狀態的裝換。
TIME_WAIT 狀態
也稱爲2MSL等待狀態,每一個具體TCP實現必須選擇一個報文段最大生存時間MSL。它是任何報文段被丟棄前在網絡內的最長時間。對一個具體實現所給定的MSL值,處理的原則是:當TCP執行一個主動關閉,併發回最後一個ACK,該鏈接必須在TIME_WAIT狀態停留的時間爲2倍的MSL。這樣可以讓TCP再次發送最後的ACK以防這個ACK丟失(另外一端超時並重發最後的FIN)。
FIN_WAIT_2 狀態
在FIN_WAIT_2狀態咱們已經發出了 FIN,而且另外一端也已對它進行確認。除非咱們在實行半關閉,不然將等待另外一端的應用層意識到它已收到一個文件結束符說明,並向咱們發一個 FIN 來關閉另外一方向的鏈接。只有當另外一端的進程完成這個關閉,咱們這端纔會從FIN_ WAIT_2狀態進入TIME_WAIT狀態。
這意味着咱們這端可能永遠保持這個狀態。另外一端也將處於 CLOSE_WAIT狀態,並一直保持這個狀態直到應用層決定進行關閉。
TCP首部中的RST位,用於「復位」,主要在下列三個場景中:
(1)到不存在的端口的鏈接請求
當鏈接請求到達時,目的端口沒有進程正在監聽,這個時候,就會發回RST報文告訴請求端;
(2)異常終止一個鏈接
客戶端斷開鏈接時,有可能不是經過發送FIN報文,而是發送RST進行復位,這稱爲異常釋放。異常終止一個鏈接對應用程序來講有兩個優勢:
丟棄任何待發數據並當即發送復位報文段;
RST的接收方會區分另外一端執行的時異常關閉仍是正常關閉。
(3)檢測半打開鏈接
若是一方已經關閉或異常終止鏈接而另外一方卻還不知道,咱們將這樣的 T C P鏈接稱爲半
打開。 任何一端的主機異常均可能致使發生這種狀況。只要不打算在半打開鏈接上傳輸數據,仍處於鏈接狀態的一方就不會檢測另外一方已經出現異常。
兩個應用程序同時彼此執行主動打開的狀況是可能的,儘管發生的可能性極小。每一方
必須發送一個 SYN,且這些SYN必須傳遞給對方。 這又稱爲同時打開。
當出現同時打開的狀況時,兩端幾乎在同時發送 SYN,並進入SYN_SENT狀態。當每一端收到 SYN時,狀態變爲 SYN_RCVD,同時它們都再發SYN並對收到的 SYN進行確認。當雙方都收到 SYN及相應的ACK時,狀態都變遷爲ESTABLISHED 。一個同時打開的鏈接須要交換4個報文段,比正常的三次握手多一個。
當應用層發出關閉命令時,兩端均從ESTABLISHED變爲FIN_WAIT_1。這將致使雙方各發送一個FIN,兩個FIN通過網絡傳送後分別到達另外一端。收到FIN後,狀態由FIN_WAIT_1變遷到 CLOSING,併發送最後的 ACK。當收到最後的 ACK時,狀態變化爲TIME_WAIT 。同時關閉和正常關閉使用的段交換數目相同。
TCP與UDP的區別至關大,它充分體現了數據傳輸時各類控制功能,能夠進行丟包時的重發控制,還能夠對次序亂掉的分包進行順序控制。TCP經過校驗和、序列號、確認應答、重發控制、鏈接管理以及窗口控制等機制實現可靠性傳輸。
在創建TCP鏈接的同時,也能夠肯定發送數據包的單位,咱們也能夠稱爲「最大消息長度」(MSS:Maximum Segment Size),最理想的狀況時,最大消息長度正好是IP中不會被分片處理的最大數據長度。
TCP在發送數據時,會以MSS大小爲單位對數據進行分割發送。MSS大小在三次握手時計算所得,兩端發送創建鏈接的請求時,會在TCP首部中寫入MSS選項,選二者較小的值。
TCP以一個段爲單位發送數據,每發送一個段就會接收到一個確認應答的處理,這樣容易形成傳輸負載變重,段的往返時間越長,性能越低。爲了解決這一缺點,TCP引入了「窗口」的概念,發送端在發送了一個報文段後沒必要要一直等待確認應答,而是繼續發送。
窗口大小指無需等待確認應答而能夠繼續發送數據的最大值,圖中窗口大小是4個報文段。
該圖①中,能夠看到滑動窗口的大小是4個報文段,報文段1001之前,接收端已經確認應答,報文段5001是未發送的數據,中間的報文段則是已經發送完成,正在等待確認應答的部分。當接收端確認數據後,這個滑動窗口不斷的往右移動,窗口兩個邊沿的相對運動增長或減小了窗口的大小。
(1)窗口左邊沿向右邊沿靠近爲窗口合攏。這種現象發生在數據被髮送和確認時。
(2)窗口右邊沿向右移動,將容許發送更多的數據,稱爲窗口張開。這種現象發生在接收端讀取了已經確認的數據並釋放了TCP的接收緩存。圖③中則說明發送端已經收到了接收端的確認應答,窗口向右移動。
若是左邊沿達到右邊沿,則稱爲一個零窗口,此時發送方不可以發送任何數據。
TCP提供可靠的運輸層。它使用的方法之一就是確認從另外一端收到的數據。但數據和確認都有可能會丟失。 TCP經過在發送時設置一個定時器來解決這種問題。若是當定時器溢出時尚未收到確認,它就重傳該數據。 當使用了窗口控制,某些確認應答即使丟失也無需重發。
其次,當某一個報文段在傳輸的過程當中丟失,接收端若是收到一個本身應該接收序號之外的數據時,會針對當前爲止收到的數據返回確認應答,通知發送端下一個要發送的數據序號,若是發送端連續3次收到同一個確認應答,則會對其對應的數據進行重發,無需等待超時定時器溢出,這就是快速重傳算法。
有這樣一種場景,發送端按照本身的實際狀況來發送數據,可是接收端可能處理數據包的能力比較弱,或者一直在處理其餘事情,沒法接收任何的數據,此時,發送端發來的數據就會被丟棄,從而又會觸發重發機制,形成資源的浪費。
爲了解決這個問題,TCP提供了一種機制,可讓發送端根據接收端的實際接收能力來控制發送的數據量,這就是流控制。在TCP首部中,有專門的字段來通知窗口的大小。在接收端發送確認應答報文時,會在窗口大小字段中標明本身目前的接收能力。不過,接收端的這個緩存區一旦溢出,窗口大小的值隨即被設置爲一個更小的值來通知給發送端。這就造成了一個完整的TCP流控制。
若是接收端發送的窗口更新通知丟失,則雙發可能由於等待對方而使鏈接終止:發送方等待容許它繼續發送數據的窗口更新,接收方等待接收數據。這樣就會形成死鎖,致使沒法繼續通訊,爲避免此類問題的發生,發送端使用一個堅持定時器,定時發送一個窗口探測數據段,以獲取最新的窗口大小的值。
有了TCP的窗口控制,收發主機之間即便再也不以一個數據段爲單位發送確認應答,也可以連續發送大量數據包,但在網絡出現擁堵時,忽然發送一個較大的數據,極有可能致使整個網絡的癱瘓。爲了防止該問題出現,TCP引入了「擁塞窗口」概念,而且經過「慢啓動」算法,用來調節發送端所要發送的數據量。
當創建TCP鏈接時,擁塞窗口被初始化爲1個報文段,每收到一個ACK,擁塞窗口的值就加1,在發送數據包時,將擁塞窗口的大小和接收端的通知窗口大小作比較,取較小的值,發送比該值還要小的數據量。隨着包的往返發送,擁塞窗口以指數函數增加,擁堵情況激增,可能致使網絡擁塞的發生。爲了解決該問題,TCP引入了「慢啓動閾值」的概念,當擁塞發生(超時或收到重複確認) 時,將慢啓動閾值設置成擁塞窗口的一半,只要擁塞窗口的值超出這個閾值,則只容許如下面比例放大擁塞窗口:
此外,若是是超時引發了擁塞,則擁塞窗口被設置爲1個報文段(這就是慢啓動)。當新的數據被對方確認時,就增長擁塞窗口,但增長的方法依賴於咱們是否正在進行慢啓動或擁塞避免。若是擁塞窗口小於或等於慢啓動閾值,則正在進行慢啓動,不然正在進行擁塞避免。慢啓動一直持續到咱們回到當擁塞發生時所處位置的一半的時候才中止,而後轉爲執行擁塞避免。
(1)Nagle算法
該算法是指發送端即便還有應該發送的數據,可是若是這部分數據不多的話,則延遲發送。僅在知足如下兩種條件中任意一種條件才能發送數據,不然暫時等待:
已發送的數據都已經收到確認應答;
能夠發送最大段長度MSS的數據。
(2)延遲確認應答
若是接收端每次馬上回復確認應答,可能會返回一個較小的窗口,由於剛接收完數據,緩存區已滿。當發送端收到這個較小的窗口後,則會以它爲上限發送數據,下降了網絡利用率。
(3)捎帶應答
TCP的確認應答通常會和回執數據一塊兒回發給發送端,這樣能夠減小收發的數據量。