由于面試中經常會問到TCP協議的一些細節,比如三次握手的詳細過程、斷開連接的過程、滑動窗口、擁塞控制等方面的內容,因此這里就整理下。
一.傳輸層協議
傳輸層主要是包含兩個協議,即TCP和UDP協議。
UDP (User Datagram Protocol):基于UDP協議的上層協議包括 DNS,RIP,DHCP,NFS等。傳送數據前不需要先建立連接。
TCP (Transmission Control Protocol):基于TCP協議的上層協議包括SMTP,Telnet,HTTP,FTP等。TCP是面向連接的。
由于傳輸層使用IP+端口號使得不同主機上的進程可以通信,也就是Socket,如192.168.1.1:8080。端口號是16位,最大為65535。其中,0-1023是保留端口號,如常見的有FTP 21, Telnet 23,SMTP 25, DNS 53, HTTP 80等。
二.UDP協議簡介
UDP協議非常的簡單,僅僅在IP協議上增加了一點點功能。主要特點是:
- 無連接。
- 盡最大努力交付。
- 面向報文。對應用層交下來報文不拆分也不合并,直接添加首部交給IP層。因此若報文太長,就會讓IP傳輸很長時間,若報文太短,會使得大量空間浪費在各類協議首部,降低傳輸效率。
- 支持1對1,1對多,多對多。
- 沒有擁塞控制。
- 報文首部開小,只有8個字節。包含源端口號、目的端口號、長度和校驗和。
三. TCP概述
TCP協議的特點是:
- 面向連接
- 點對點(一對一)
- 可靠交付
- 面向字節流,也就是說僅僅把上層協議傳遞過來的數據當成字節傳輸。
為了實現TCP上述的特點,TCP協議需要解決的是面向連接(建立連接和關閉連接的方式)、可靠傳輸(錯誤確認和重傳)、流量控制(發送方和接收方的傳輸速率協調)、擁塞控制四個方面。
四 TCP協議首部格式
TCP協議首部最小長度是20字節,首部有一個長度可變的選項部分,最大40字節,所以TCP首部長度是20-60字節大小。具體如圖:
選取部分字段說明:
序號:TCP傳輸的時候每一個字節都按順序編號;協議中的序號是本報文段所發送數據第一個字節的序號。序號也用于建立和結束連接時候使用。
確認號:用于可靠傳輸中,返回確認報文序號。
數據偏移:指出數據段在報文中開始的位置。
窗口:可靠連接和流量控制中所用到的窗口大小。
上圖中有六個控制位,對于建立和結束連接非常關鍵,解釋如下:
- URG(Urgent):緊急字段,可以讓該報文不按報文順序優先被處理。比如用戶突然終止傳輸關閉連接。
- ACK(Acknowledge):所有建立連接后傳送的報文ACK必須為1.
- PSH(Push):發送方講該報文推送向前,可以不用等緩存填滿先提交給應用程序。
- RST(Reset):連接出現嚴重差錯時候設為1,重新建立連接。也可用于拒絕建立連接。
- SYN(Synchronize):建立連接時候的同步標志。SYN=1而ACK=0時表示建立連接請求。
- FIN(Finish):終止時標志位。
另外,在選項中有這么幾種選擇:
- 最大報文長度MSS(Maxium Segment Size),指的是一個TCP報文數據段的最大長度。要盡可能大一些但是又不需要IP拆分。推薦是536字節,這樣真個TCP報文長度是 536+20 = 556字節。
- 窗口擴大選項。可用于控制傳輸窗口大小。
- 時間戳。非常有用。可以用于 1)計算往返時間RTT 2)區分重復報文。因為報文的序號只能是2^32-1個,所以很容易就重復了,加上時間戳可以進行區分。
五 TCP協議的建立連接過程(三次握手)
著名的三次握手協議,一圖勝萬語。
對上圖的說明:
SYN和ACK已經說過了。seq就是首部中的序號字段,圖中x和y都是隨機生成的,然后收到后返回確認會將其+1.注意發送方和接收方的狀態變化如下:
發送方: CLOSED-->SYN-SENT-->ESTABLISHED
接收方: CLOSED-->LISTEN-->SYN_RECEIVED-->ESTABLISHED
為什么需要三次握手?主要是為了防止“已失效的連接請求”。加入只要兩次握手,即A發送請求B返回確認就可以建立連接。可能會出現以下情況:比如,A發送的第一個連接請求并未丟失,而是延滯了,此時A已經放棄了建立連接,但是B又最終收到了,于是返回ACK給A,這樣就錯誤的建立了連接。
六 TCP協議關閉連接過程(四次握手)
釋放連接的過程也見下圖:
對上圖的說明:FIN、ACK字段之前已經講過。seq是序列號,圖中每一個新的字母都表示隨機生成。釋放連接的狀態變化:
發送方:ESTABLISHED-->FIN-WAIT_1-->FIN-WAIT_2-->TIME-WAIT-->CLOSED
接收方:ESTABLISHED-->CLOSE-->WAIT-->LAST-ACT-->CLOSED
注意,釋放連接包含兩個來回。前兩次握手代表發送方不再傳輸數據了。后兩次握手代表接收方不再傳輸數據了,因為TCP是全雙工通信,二者是可以同時發送消息和接受消息的。所以圖中B的CLOSE-WAIT階段,仍然可以傳輸數據。
為什么A在發送確認后還有TIME-WAIT的階段?有兩個理由:
- A發送的最后一個ACK必須到達B。如果B沒有收到該ACK,可能會再次發送FIN+ACK。如果此時A關閉了,B就不可能收到ACK了,也就無法正常關閉。
- 同三次握手一樣,A等待一段時間,可以上網絡中本次連接的延滯的請求都發送到位,然后再關閉連接,這樣網絡里面就不會再剩下本次連接的請求了。
TIME-WAIT設置為多久?更具上述分析,一般會把TIME-WAIT時間設置為2MSL,MSL代表最長報文壽命(Maximum Segment Lifetime)。也就是說,如果一段報文最長壽命為2分鐘,會讓A等待4分鐘后再關閉。
七 TCP協議可靠傳輸的實現
基本原理
考慮A發送數據到B接受的情況。記報文為M。
停止等待協議:A每發送完一個報文M,就等候B對其確認;收到確認后繼續發送。A設置超時重傳機制。因此這種機制也成為自動重傳請求ARQ(Automatic Repeat reQuest)。連續ARQ協議/窗口滑動協議
顯然,每次只發送一個報文然后等待確認效率太低。所以可以約定每次發送多個報文,然后采用累積確認的方式。B對按序到達的最后一個分組發送確認。如果中間發生丟失包的情況,A需要回退到確認的報文重新發送。如圖所示。
說明一下:A的發送窗口大小是根據B接受窗口設置的。也就是說A發送的報文速度不能超過B處理報文的速度。
TCP中對于超時重傳時間的選擇是根據平均往返時間RTT來計算的。也就是說,如果A超過一個報文平均往返時間沒有收到確認,就會重新發送報文。
八 TCP協議流量控制
流量控制,簡單來說就是不能發送的太快,以免處理不完,也不能發送的太慢,以免浪費資源。TCP協議中,建立連接之時,B會告訴A自己接受窗口的大小,A的窗口大小不會超過這個大小。
傳輸過程中,B會根據自己數據緩存的情況給A返回自己的窗口大小,例如,剛開始發送數據時,B的緩沖區為空,設置窗口大小為300,A開始發送;但是由于A發送的太快,B緩沖區漸漸變滿,就會將接受窗口的大小設為100;如果B的緩沖區滿了,還可能將窗口大小設為0,A就停止發送,直到B重新發送了一個窗口大小。
九 TCP協議擁塞控制
慢開始、擁塞避免、快重傳、快恢復
擁塞控制發生在網絡中負載太大,比如路由器IP包隊列堆滿了,就會丟棄尾部的包,從而導致TCP層數據的丟失。擁塞控制就是要避免網絡數據量太大導致傳輸效率、速度降低。
常見的TCP擁塞控制方法包括四種:
- 慢開始
- 擁塞避免
- 快重傳
- 快恢復
慢開始是指,TCP開始建立連接發送數據后,每次發送的報文段數從1開始。不能一開始就發送大量的報文段。如果網絡暢通,發送方每個數據往返來回就把發送報文的數據量增加一倍。注意,這里的報文數據量指的就是窗口大小。
這樣指數級會導致發送窗口快速增長。當超過一定值時候,就可能導致網絡擁塞了,這個值被稱為慢開始門限ssthresh。超過ssthresh后就采取擁塞避免的算法。變為發送窗口每次增長1.
如果A超過一定時間沒有收到B發來的確認,說明報文丟失了,網絡擁塞出現,此時將窗口大小設置為1,并將ssthresh設置為出現擁塞時窗口大小的一半。重新進行慢開始算法。這個過程稱為AIMD(加法增大乘法減小)。
快重傳是指,接收方B每收到一個失序的報文段(以為之前有報文段擁塞了)就立即發出重復確認。發送方如果連續收到三個重復確認就立即重傳該報文段,而無需等候為重傳計時器。如下圖:
快重傳和快恢復配合使用。如果發送方連續收到三次重復確認時,就執行“乘法減小”策略。但是不同之處在于,此時不再將窗口設置為1(慢開始算法),而是執行擁塞避免算法。如下圖:
增加了擁塞控制算法后,TCP協議中發送方窗口大小設置為:
Min[擁塞窗口,接收方窗口]
隨機早期檢測RED
對TCP擁塞控制影響最大的是路由器的分組丟棄策略。路由器按照先進先出的原則發包。當隊列滿了之后,就會將超出隊列的包一起丟棄。
由于一個路由器的包是來自于不同TCP協議客戶端,這些發送方會同時發現丟包了,于是執行擁塞算法,此時網絡中流量驟然下降,待網絡恢復后,通信量又會突然增大。
為了避免這種情況出現,可以讓路游戲采用隨機早期檢測算法RED(Random Early Detection)。方法很簡單,設定一個隊列最小閾限THmin和隊列最大閾限THmax。當隊列長度<THmin時,正常發包;當隊列長度介于THmin和THmax之間時,按照一定概率p隨機丟包;當隊列長度大于THmax時,將新到達的包丟掉。概率p可以隨著隊列長度增加逐漸從0增加到1.THmax一般設置為THmin的兩倍。
通過這種算法,就可以避免開始所述的網路流量突然增大和突然縮小的情況。
參考文獻
《計算機網絡(第五版)》謝希仁,文中所有內容和配圖均來自本書第五章