天天看點

TCP 協定如何保證可靠傳輸

一、綜述

1、确認和重傳:接收方收到封包就會确認,發送方發送一段時間後沒有收到确認就重傳。

2、資料校驗

3、資料合理分片和排序:

  UDP:IP資料報大于1500位元組,大于MTU.這個時候發送方IP層就需要分片(fragmentation).把資料報分成若幹片,使每一片都小于MTU.而接收方IP層則需要進行資料報的重組.這樣就會多做許多事情,而更嚴重的是,由于UDP的特性,當某一片資料傳送中丢失時,接收友善無法重組資料報.将導緻丢棄整個UDP資料報.

  tcp會按MTU合理分片,接收方會緩存未按序到達的資料,重新排序後再交給應用層。

4、流量控制:當接收方來不及處理發送方的資料,能提示發送方降低發送的速率,防止包丢失。

5、擁塞控制:當網絡擁塞時,減少資料的發送。

二、滑動視窗

  上面籠統地說了tcp保證可靠傳輸的機制,下面說說如何用滑動視窗來實作。

為什麼要使用滑動視窗

       因為發送端希望在收到确認前,繼續發送其它封包段。比如說在收到0号封包的确認前還發出了1-3号的封包,這樣提高了信道的使用率。但可以想想,0-4發出去後可能要重傳,是以需要一個緩沖區維護這些封包,是以就有了視窗。

TCP 協定如何保證可靠傳輸

  RTT:往返時間。

視窗是什麼

接收視窗:

   

TCP 協定如何保證可靠傳輸

  “接收視窗”大小取決于應用(比如說tomcat:8080端口的監聽程序)、系統、硬體的限制。圖中,接收視窗是31~50,大小為20。

  在接收視窗中,黑色的表示已收到的資料,白色的表示未收到的資料。

  當收到視窗左邊的資料,如27,則丢棄,因為這部分已經傳遞給主機;

  當收到視窗左邊的資料,如52,則丢棄,因為還沒輪到它;

  當收到已收到的視窗中的資料,如32,丢棄;

  當收到未收到的視窗中的資料,如35,緩存在視窗中。

發送視窗:

TCP 協定如何保證可靠傳輸

  發送視窗的大小swnd=min(rwnd,cwnd)。rwnd是接收視窗,cwnd用于擁塞控制,暫時可以了解為swnd= rwnd =20。

  圖中分為四個區段,其中P1到P3是發送視窗。

  tips:發送視窗以位元組為機關。為了友善畫圖,圖中展示得像以封包為機關一樣。但這不影響了解。

三、重傳和确認

什麼時候發确認:這是一個複雜的政策。我們這裡先簡單地認為每收到一個封包就發一個确認。

怎麼确認(累計确認):

  情況1:發送ack=31(為什麼這個也要發,這個确認可以用于後面的擁塞控制)

TCP 協定如何保證可靠傳輸

  情況2:發送ack=34,并把接收視窗左邊緣設定成34,右邊緣設定成53

TCP 協定如何保證可靠傳輸

  累計确認的好處:情況1中ack=31比描述收到32和33簡單;壞處:可能要重傳已經接收的資料。

發送方收到确認時怎麼處理:

   

TCP 協定如何保證可靠傳輸

  情況1:收到ack=31,什麼都不做,或者說繼續發送可用視窗中的内容,如42~50

  情況2:收到ack=34,發送視窗視窗的左邊緣設定成34,右邊緣設定成53

什麼時候重傳:因為每個封包都有逾時計數器,逾時才重傳。逾時重傳時間的選擇也是一個政策。

tcp緩存和視窗的關系:視窗是緩存的一部分。

發送緩存=發送視窗+ P3右邊的一部分

接收緩存=接收視窗+部分已确認但主機還沒處理完的資料。

四、流量控制

一圖流,簡單來說就是接收方處理不過來的時候,就把視窗縮小,并把視窗值告訴發送端。

  

TCP 協定如何保證可靠傳輸

當視窗值為0,而接受方把視窗值恢複(比如ACK=1,ack=601,rwnd=200),但确認丢失,進入互相等待的死鎖局面。是以如果視窗值為0,發送端就會開啟一個持續計數器,每個一段時間詢問一下接收方。

五、擁塞控制

swnd=min(rwnd,cwnd),cwnd就是擁塞視窗大小。

慢開始和擁塞避免

TCP 協定如何保證可靠傳輸

ssthresh:處理擁塞時參照的一個參數。例子中初始值為16,後來變為12。

當cwnd> ssthresh,cwnd以慢開始的方法指數增長;

當cwnd< ssthresh,cwnd以擁塞避免的方法線性增長。

值得注意的幾個點

1上圖是cwnd随傳輸輪次的變化,每過一個RTT就算一輪。

2逾時就可以認為是擁塞了

快重傳和快恢複:上一個算法的加強版

TCP 協定如何保證可靠傳輸

快重傳:收到3個同樣的确認就立刻重傳,不等到逾時;

快恢複:cwnd不是從1重新開始。

繼續閱讀