面向連接、可靠的、基於字節流的傳輸協議
源端口和目的端口字段——各佔 2 字節。端口是傳輸層與應用層的服務接口。傳輸層的複用和分用功能都要通過端口才能實現 。
序號字段——佔 4 字節。TCP 連接中傳送的數據流中的每一個字節都編上一個序號。序號字段的值則指的是本報文段所發送的數據的第一個字節的序號
確認號字段——佔 4 字節,是期望收到對方的下一個報文段的數據的第一個字節的序號
數據偏移——佔 4 bit,它指出 TCP 報文段的數據起始處距離 TCP 報文段的起始處有多遠。“數據偏移”的單位不是字節而是 32 bit 字(4 字節爲計算單位)
保留字段——佔 6 bit,保留爲今後使用,但目前應置爲 0
緊急比特 URG —— 當 URG ? 1 時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應儘快傳送(相當於高優先級的數據)
確認比特 ACK —— 只有當 ACK =1 時確認號字段纔有效。當 ACK =0 時,確認號無效
推送比特 PSH (PuSH) —— 接收 TCP 收到推送比特置 1 的報文段,就儘快地交付給接收應用進程,而不再等到整個緩存都填滿了後再向上交付
復位比特 RST (ReSeT) —— 當 RST = 1 時,表明 TCP 連接中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連接,然後再重新建立運輸連接
同步比特 SYN —— 同步比特 SYN 置爲 1,就表示這是一個連接請求或連接接受報文
終止比特 FIN (FINal) —— 用來釋放一個連接。當FIN = 1 時,表明此報文段的發送端的數據已發送完畢,並要求釋放運輸連接
窗口字段 —— 佔 2 字節。窗口字段用來控制對方發送的數據量,單位爲字節。
TCP 連接的一端根據設置的緩存空間大小確定自己的接收窗口大小,然後通知對方以確定對方的發送窗口的上限
檢驗和 —— 佔 2 字節。檢驗和字段檢驗的範圍包括首部和數據這兩部分。在計算檢驗和時,要在 TCP 報文段的前面加上 12 字節的僞首部
緊急指針字段 —— 佔 16 bit。緊急指針指出在本報文段中的緊急數據的最後一個字節的序號
選項字段 —— 長度可變。TCP 只規定了一種選項,即最大報文段長度 MSS (Maximum Segment Size)。MSS 告訴對方 TCP:“我的緩存所能接收的報文段的數據字段的最大長度是 MSS 個字節”
填充字段 —— 這是爲了使整個首部長度是 4 字節的整數倍
Tcp 可靠機制
1可變滑動窗口
2慢啓動
3“快速重傳(Fast retransmit)”、“快速恢復(Fast Recovery)”算法
4擁塞避免
5三次握手
6釋放連接(四次握手)
1滑動窗口的概念
TCP 採用大小可變的滑動窗口進行流量控制,窗口大小的單位是字節;
TCP 報文段首部的窗口字段的數值就是可發送窗口數值的上限,發送窗口在連接建立時由雙方商定。
2慢啓動
TCP採用慢開始和擁塞避免的方法控制發送
慢開始的思路是,先測試一下,在由小到大的增大發送窗口
具體的:預先設置一個慢開始門限,ssthresh(用於控制擁塞)
先設擁塞窗口cwnd=1,發送第一個報文,收到確認後把cwnd設爲2,在發送,收到回覆後,再把cwnd增加2個,即,收到回覆後就把cwnd增加一倍,這就是慢開始算法
具體來說,當新建連接時,cwnd初始化爲1個最大報文段(MSS)大小,發送端開始按照擁塞窗口大小發送數據,每當有一個報文段被確認,cwnd就增加1個MSS大小。這樣cwnd的值就隨着網絡往返時間(Round Trip Time,RTT)呈指數級增長,事實上,慢啓動的速度一點也不慢,只是它的起點比較低一點而已。我們可以簡單計算下:
開始 ---> cwnd = 1
經過1個RTT後 ---> cwnd = 2*1 = 2
經過2個RTT後 ---> cwnd = 2*2= 4
經過3個RTT後 ---> cwnd = 4*2 = 8
如果帶寬爲W,那麼經過RTT*log2W時間就可以佔滿帶寬。
4擁塞避免
cwnd>ssthresh就停止上述的慢開始算法而使用擁塞避免算法
擁塞避免算法就是每收到一個回覆後就把cwnd加1,直到出現擁塞
無論在慢開始還是擁塞避免時只要出現擁塞就把ssthresh設爲原值的一半(這就是乘法減小)並把cwnd設爲1,在執行慢開始算法,重複上述過程
.把ssthresh降低爲cwnd值的一半
.把cwnd重新設置爲1
.重新進入慢啓動過程。
從慢啓動可以看到,cwnd可以很快的增長上來,從而最大程度利用網絡帶寬資源,但是cwnd不能一直這樣無限增長下去,一定需要某個限制。TCP使用了一個叫慢啓動門限(ssthresh)的變量,當cwnd超過該值後,慢啓動過程結束,進入擁塞避免階段。對於大多數TCP實現來說,ssthresh的值是65536(同樣以字節計算)。擁塞避免的主要思想是加法增大,也就是cwnd的值不再指數級往上升,開始加法增加。此時當窗口中所有的報文段都被確認時,cwnd的大小加1,cwnd的值就隨着RTT開始線性增加,這樣就可以避免增長過快導致網絡擁塞,慢慢的增加調整到網絡的最佳值。
3快速重傳/快速恢復
TCP還有一種情況會進行重傳:那就是收到3個相同的ACK。TCP在收到亂序到達包時就會立即發送ACK,TCP利用3個相同的ACK來判定數據包的丟失,此時進行快速重傳,快速重傳做的事情有:
1.把ssthresh設置爲cwnd的一半
2.把cwnd再設置爲ssthresh的值(具體實現有些爲ssthresh+3)
3.重新進入擁塞避免階段。
後來的“快速恢復”算法是在上述的“快速重傳”算法後添加的,當收到3個重複ACK時,TCP最後進入的不是擁塞避免階段,而是快速恢復階段。快速重傳和快速恢復算法一般同時使用。快速恢復的思想是“數據包守恆”原則,即同一個時刻在網絡中的數據包數量是恆定的,只有當“老”數據包離開了網絡後,才能向網絡中發送一個“新”的數據包,如果發送方收到一個重複的ACK,那麼根據TCP的ACK機制就表明有一個數據包離開了網絡,於是cwnd加1。如果能夠嚴格按照該原則那麼網絡中很少會發生擁塞,事實上擁塞控制的目的也就在修正違反該原則的地方。
具體來說快速恢復的主要步驟是:
1.當收到3個重複ACK時,把ssthresh設置爲cwnd的一半,把cwnd設置爲ssthresh的值加3,然後重傳丟失的報文段,加3的原因是因爲收到3個重複的ACK,表明有3個“老”的數據包離開了網絡。
2.再收到重複的ACK時,擁塞窗口增加1。
3.當收到新的數據包的ACK時,把cwnd設置爲第一步中的ssthresh的值。原因是因爲該ACK確認了新的數據,說明從重複ACK時的數據都已收到,該恢復過程已經結束,可以回到恢復之前的狀態了,也即再次進入擁塞避免狀態。
5三次握手
6四次握手
Tcp連接建立與關閉(正常)