TCP協議傳輸數據的特點主要是面向字節流、傳輸可靠、面向連接。保證數據傳輸可靠性的方式如下:
校驗和
序列號
TCP傳輸數據時對每個字節的數據都進行了編號,這就是序列號。
確認應答
超時重傳
在進行TCP傳輸時,由于確認應答與序列號機制,也就是說發送方發送一部分數據后,都會等待接收方發送的ACK報文,并解析ACK報文,判斷數據是否傳輸成功。如果發送方發送完數據后,遲遲沒有等到接收方的ACK報文,這該怎么辦呢?而沒有收到ACK報文的原因可能是什么呢?
首先,發送方沒有接收到響應的ACK報文原因可能有兩點:
(1)數據在傳輸過程中由于網絡原因等直接全體丟包,接收方根本沒有接收到。
(2)接收方接收到了響應的數據,但是發送的ACK報文響應卻由于網絡原因丟包了。
TCP在解決這個問題的時候引入了一個新的機制,叫做超時重傳機制。簡單理解就是發送方在發送完數據后等待一個時間,時間到達沒有接收到ACK報文,那么對剛才發送的數據進行重新發送。如果是剛才第一個原因,接收方收到二次重發的數據后,便進行ACK應答。如果是第二個原因,接收方發現接收的數據已存在(判斷存在的根據就是序列號,所以上面說序列號還有去除重復數據的作用),那么直接丟棄,仍舊發送ACK應答。
那么發送方發送完畢后等待的時間是多少呢?如果這個等待的時間過長,那么會影響TCP傳輸的整體效率,如果等待時間過短,又會導致頻繁的發送重復的包。如何權衡?
由于TCP傳輸時保證能夠在任何環境下都有一個高性能的通信,因此這個最大超時時間(也就是等待的時間)是動態計算的。
在Linux中(BSD Unix和Windows下也是這樣)超時以500ms為一個單位進行控制,每次判定超時重發的超時時間都是500ms的整數倍。重發一次后,仍未響應,那么等待2500ms的時間后,再次重傳。等待4500ms的時間繼續重傳。以一個指數的形式增長。累計到一定的重傳次數,TCP就認為網絡或者對端出現異常,強制關閉連接。
連接管理
連接管理就是三次握手與四次揮手的過程,這里不再贅述。保證可靠的連接,是保證可靠性的前提。
流量控制
接收端在接收到數據后,對其進行處理。如果發送端的發送速度太快,導致接收端的結束緩沖區很快的填充滿了。此時如果發送端仍舊發送數據,那么接下來發送的數據都會丟包,繼而導致丟包的一系列連鎖反應,超時重傳呀什么的。而TCP根據接收端對數據的處理能力,決定發送端的發送速度,這個機制就是流量控制。
擁塞控制
TCP傳輸數據的過程中,發送端如果一開始就發送大量的數據,就可能造成一些問題,網絡可能在開始的時候就很擁堵,如果繼續往網絡中扔出大量數據,那么這個擁堵就會加劇。擁堵的加劇就會產生大量的丟包,從而導致大量的超時重傳,嚴重影響傳輸。
所以TCP引入了慢啟動的機制,在開始發送數據時,先發送少量的數據探路。探清當前的網絡狀態,再決定多大的速度進行傳輸。這時候就引入一個叫做擁塞窗口的概念。發送剛開始定義擁塞窗口為 1,每次收到ACK應答,擁塞窗口加 1。在發送數據之前,首先將擁塞窗口與接收端反饋的窗口大小比對,取較小的值作為實際發送的窗口。