TCP服務
TCP:可靠、有鏈接、面向字節流。
使用TCP協議通信的雙方必須先建立連接,然後才能開始數據讀寫。TCP連接是全雙工的。
有鏈接:TCP協議的這種連接是一對一的,所以基於廣播和多播的應用程序不能使用TCP服務,應使用無連接的UDP協議。
字節流與數據報
字節流:發送端執行的寫操作次數與接收端執行的讀操作次數之間沒有任何數量關係。
數據報:發送端應用程序每執行一次寫操作,UDP模塊就將其封裝成一個UDP數據報併發送。接收端必須對每一個數據報進行讀操作,否則會丟包。
可靠:TCP採用發送應答機制,發送端每個TCP報文段都必須得到接收方的應答,才認爲這個TCP報文段傳輸成功。其次,TCP採用超時重傳,發送端在發送TCP報文之後啓動定時器,如果在定時時間內沒有收到應答,將會重發該報文段。
TCP頭部
- 16位源/目的端口號:進行TCP通信時,客戶端通常使用系統自動選擇的臨時端口號,而服務器使用的是知名服務器端口號。
- 32位序號:一次TCP通信(從TCP連接到斷開)過程中某一個傳輸方向上的字節流的每個字節的編號。一個TCP報文被初始化爲某個隨機值ISN(初始序號值),某個報文傳送的是1025~2048字節,則該報文序號值ISN+1025。
- 32位確認號:用來對另一方TCP報文發來的響應,其值是收到的TCP報文的序號值加 1 。
- 4位頭部長度:4位4字節,所以最長是60字節。
- 6位標誌位
- URG標誌:緊急指針
- ACK:確認號
- PSH:提示接收端應用程序應立即從TCP接收緩衝區中讀走數據
- RST:要求對方重新建立連接
- SYN:請求建立一個連接
- FIN:通知對方本端要關閉連接了
- 16位窗口大小:TCP流量控制
- 16位校驗和:TCP可靠傳輸的保障
- 16位緊急指針:一個正的偏移量
TCP連接的建立與關閉
TCP連接的建立與關閉又稱三次握手與四次揮手
虛線表示服務器端的狀態轉移,實線表示客戶端的狀態轉移。
TME_WAIT狀態
誰主動斷開連接誰進入TME_WAIT狀態。TME_WAIT需要等待3MSL(報文段最大生存時間)的時間,才能關閉。
TME_WAIT狀態存在的原因:
- 可靠的終止TCP連接
- 保證讓遲到的TCP報文有足夠的時間被識別並丟棄。當沒有TME_WAIT狀態時,斷開當前連接並在端口上創建新的連接,新的連接有可能接收到對方發來的上次連接的TCP報文,
TCP重要機制
確認應答
接收到對端的數據後返回一個標誌位爲ACK的確認數據報。確認序號表示的含義是該序號之前的所有數據都收到了。
超時重傳
TCP服務器爲了保證數據的可靠傳輸,TCP模塊爲每一個TCP報文都維護一個重傳定時器,該定時器在TCP報文段第一次被髮送時啓動。如果超過時間沒有收到接收方的應答,TCP模塊將重傳TCP報文並重置定時器。
擁塞控制
TCP模塊的一個重要任務擁塞控制,就是提高網絡利用率,降低丟包率、並保證網絡資源對每條數據流的公平性。
TCP擁塞控制包含四個部分:慢啓動、擁塞避免、快速重傳、快速恢復。
擁塞控制的最終受控變量是發送端向網絡端向網絡中一次連續寫入(收到其第一個數據的確認之前)的數據量,稱爲SWND(發送窗口),所以它限制了一次發送TCP報文段的數量。這些報文段(僅數據部分)的長度最大爲SMSS(發送者最大報文大小),值一般爲MSS。
合理選擇SWND(發送窗口)
SWND太小:引起明顯的網絡延遲
SWND太大:容易導致網絡擁塞
接收方可以通過接收通告窗口來控制發送端的發送窗口。但是這樣仍不夠。所以引入擁塞窗口(CWDN)。
SWND 的值是 RWND 和 CWND 中較小值。
慢啓動與擁塞避免
TCP連接建立後,CWND被設爲初始值 1W,大小爲2~4SMSS。此時發送端最多發送 1W 字節的數據。然後,發送端每接收到一個來自接收端的確認,CWND就增加,公式爲:
CWND += MIN(N,SMSS)
N是此次確認中包含的之前未被確認的字節數。CWND將會按照指數形式擴大。
慢啓動按指數形式擴大,如果基數太大就會膨脹很快,所以TCP擁塞控制需要另一個狀態變量:慢啓動門限。當 CWND 超過了門限值,TCP擁塞控制將進入 擁塞避免 階段。
擁塞避免 :使 CWND 按線性增長,緩慢擴大。
慢啓動與擁塞避免中發生擁塞
雖然有慢啓動和擁塞控制,但是擁塞依舊可能發生,擁塞在兩個階段都有可能發生。
擁塞發生的依據:
- 傳輸超時,TCP重傳定時器溢出 ,仍使用慢啓動和擁塞避免。但是慢啓動門限值會改變。新慢啓動門限值 = max(已發送單位收到確認的字節數/2,2*SMSS) CWND <= SMSS
- 接收到重複的確認報文,使用快速重傳和快速恢復。如果是發生在重傳定時器溢出之後,則按傳輸超時處理。
快速重傳和快速恢復
有多種可能接收到重複的確認報文,比如:TCP報文段丟失,或者接收端收到亂序TCP報文段並重排之等。擁塞控制算法需要判斷是否發生了網絡擁塞,或是TCP報文段丟失。
如果發送端收到了連續三個重複的確認報文,就認爲是擁塞發生了,使用快速重傳和快速恢復處理擁塞狀況。
- 當收到第三個相同的確認報文時計算新的慢啓動門限值,然後重傳丟失的報文,並將設置 CWND = 新的門限值 + 3 * SMSS
- 每次收到 1 個重複的確認時,設置CWND = CWND + SMSS ,此時發送端可以發新的TCP報文段。
- 當收到新報文段的確認時,設置 CWND = 新的門限值。
延時應答、捎帶應答
延時應答
當接收到數據後立即確認應答,此時返回的窗口大小是較小的,傳輸效率較低。
窗口越大傳輸效率越高,在避免擁塞的情況下,儘量擴大窗口的大小。
不能進行延時應答的情況:
- 數量限制: 每隔N個包應答一次
- 時間限制: 超過最大延遲時間應答一次;
捎帶應答
在延遲應答的基礎上, 很多情況下, 客戶端服務器在應用層也是 “⼀發⼀收” 的,意味着客戶端給服務器說了 “How are you”, 服務器也會給客戶端回⼀一個 “Fine, thank you”。
那麼這個時候ACK就可以搭順風車, 和服務器迴應的 “Fine, thank you” 一起發送給客戶端。