TCP協(xié)議詳解
介紹TCP協(xié)議之前,先區(qū)分一下TCP協(xié)議,和TCP/IP體系結(jié)構(gòu)。TCP協(xié)議是TCP/IP協(xié)議體系中運(yùn)輸層的協(xié)議之一,提供可靠的運(yùn)輸層服務(wù),具有面向連接,面向字節(jié)流,提供可靠交付,據(jù)用流量控制和擁塞控制等特點(diǎn)。
先簡單介紹一下TCP/IP體系結(jié)構(gòu), 以便于清晰一下自己所在協(xié)議棧的位置。
OSI七層太過復(fù)雜,且沒有在開始的時(shí)候快速占領(lǐng)市場(chǎng)。當(dāng)時(shí)一直到現(xiàn)在使用的都是TCP/IP體系結(jié)構(gòu),但是為了更好的闡述基本原理,還是按照五層體系結(jié)構(gòu)來劃分說明。

TCP/IP協(xié)議族

傳輸控制協(xié)議TCP
概述
協(xié)議特點(diǎn):
- 面向連接的協(xié)議:建立連接、關(guān)閉連接
- 點(diǎn)對(duì)點(diǎn):連接只能有2個(gè)端點(diǎn)
- 可靠交付:無差錯(cuò)、不丟失、不重傳、按順序交付給應(yīng)用層
- 全雙工:通信雙方在任何時(shí)候都能夠發(fā)送數(shù)據(jù)
- 面向字節(jié)流:每個(gè)字節(jié)都有序號(hào),比如說累積確認(rèn),確認(rèn)號(hào)就是下一個(gè)字節(jié)編號(hào)
報(bào)文剖析

下面對(duì)部分首部字段詳細(xì)說明:
- 序號(hào):是報(bào)文段數(shù)據(jù)部分的字節(jié)的序號(hào)。在首部中占4個(gè)字節(jié),2的32次冪個(gè)序號(hào)。超過后,回到0。之所以說TCP面向字節(jié)流,是因?yàn)槊總€(gè)字節(jié)都有一個(gè)序號(hào)。如序號(hào)是301,數(shù)據(jù)共100字節(jié),那么最后一個(gè)字節(jié)的序號(hào)是400。所以下一個(gè)報(bào)文段的序號(hào)從401開始。
- 確認(rèn)號(hào):是作為接受方的一端在收到tcp報(bào)文后,期望下一次收到的字節(jié)的序號(hào),繼續(xù)上文序號(hào)的例子,收到301,數(shù)據(jù)長度100,那么再ack這個(gè)報(bào)文的時(shí)候,確認(rèn)號(hào)應(yīng)該是401(301+100)
這里有個(gè)重要的概念——累積確認(rèn),就是說,如果:
確認(rèn)號(hào)=N,表明,到序號(hào)N-1為止的所有數(shù)據(jù)都已經(jīng)正確收到!
數(shù)據(jù)偏移:數(shù)據(jù)部分距離首部有多遠(yuǎn)(因?yàn)閠cp報(bào)文段中包含可變長度的選項(xiàng),不能根據(jù)位數(shù)定位數(shù)據(jù)部分)
控制位URG
控制位ACK:ACK=1時(shí)候,確認(rèn)號(hào)字段才有意義,說明該報(bào)文包含確認(rèn)
控制位PSH:為1時(shí),表明接收方收到報(bào)文后要盡快交付給應(yīng)用層
控制位RST:Reset復(fù)位,連接出現(xiàn)嚴(yán)重差錯(cuò),必須釋放連接然后再重建連接
控制位SYN:建立連接的時(shí)候使用,用來同步報(bào)文起始序號(hào)
控制位FIN:finish,釋放連接的時(shí)候使用
窗口:占2字節(jié),表明作為接收方,我還有多少字節(jié)的緩沖空間來接受新的字節(jié),數(shù)據(jù)的單位是字節(jié),該值作為發(fā)送方設(shè)置其發(fā)送窗口大小的依據(jù)
可靠傳輸
滑動(dòng)窗口動(dòng)態(tài)視頻-Normal
滑動(dòng)窗口動(dòng)態(tài)視頻-Error

右邊的圖反轉(zhuǎn)一下更容易理解。
流量控制
接收方來不及接收,會(huì)造成數(shù)據(jù)丟失。所謂流量控制就是讓發(fā)送發(fā)不要發(fā)送的太快。
主要利用滑動(dòng)窗口來控制。
這里有個(gè)知識(shí)點(diǎn),就是當(dāng)接收窗口為0之后,如何打破死鎖局面。打破的方法就是發(fā)送端發(fā)送零窗口探測(cè)報(bào)文(似乎也是keep alive報(bào)文),接收方在確認(rèn)這個(gè)報(bào)文的時(shí)候,將新的窗口值帶上,如果不是0,死鎖就打破了。
擁塞控制
- 慢開始
- 擁塞避免
- 快速重傳
- 快速恢復(fù)
連接管理
三次握手建立連接,四次交互關(guān)閉連接。連接的狀態(tài)變化。
建立連接
經(jīng)過下圖的三次握手之后,連接被成功建立。

- 客戶機(jī)A請(qǐng)求服務(wù)器B打開連接,進(jìn)入SYN-SENT狀態(tài)
- 服務(wù)器B響應(yīng)“打開連接的請(qǐng)求”,進(jìn)入SYN-RCVD狀態(tài)
- 客戶機(jī)A收到SYN-SEND的ack, 進(jìn)入ESTABLISHED狀態(tài),并再一次確認(rèn)B的響應(yīng),這次可以攜帶數(shù)據(jù)也可以不攜帶數(shù)據(jù),SYN=1, ACK=1, seq=x+1, ack=y+1, 機(jī)器B在收到此確認(rèn)后,進(jìn)入ESTABLISHED狀態(tài)
這期間server或會(huì)設(shè)定MSS等參數(shù)
釋放連接

- 機(jī)器A請(qǐng)求關(guān)閉連接,發(fā)送終止信號(hào),進(jìn)入FIN-WAIT階段一(終止等待1),等待機(jī)器B的確認(rèn)
- B收到A的終止信號(hào),隨即發(fā)送確認(rèn),并通知上層進(jìn)程,進(jìn)入CLOSE-WAIT,關(guān)閉等待狀態(tài);這時(shí)候從A到B這個(gè)方向的連接釋放了,TCP連接的狀態(tài)為辦關(guān)閉狀態(tài)。A已經(jīng)沒有數(shù)據(jù)要發(fā)送了,但是B可能還有數(shù)據(jù)要發(fā)送,并可以繼續(xù)發(fā)送;
- 當(dāng)A收到B對(duì)終止信號(hào)的確認(rèn),A進(jìn)入終止等待2,等待B最終的確認(rèn);當(dāng)B沒有數(shù)據(jù)發(fā)送的時(shí)候,B會(huì)再次確認(rèn)A的終止信號(hào)(意在關(guān)閉B到A方向上的連接),B進(jìn)入LAST-ACK狀態(tài)
- A收到B對(duì)終止信號(hào)的第二次確認(rèn)后,A發(fā)送對(duì)確認(rèn)的確認(rèn),進(jìn)入TIME-WAIT狀態(tài);當(dāng)B收到確認(rèn)后,關(guān)閉連接回收資源;當(dāng)2MSL之后,A也關(guān)閉連接,釋放資源
MSL: max segment lifetime, 最大報(bào)文壽命
MSS: max segment size 最大報(bào)文長度
TIME-WAIT階段等待2MSL的作用:
1. 如果B沒有收到最后的ACK, B會(huì)重傳FIN=1, 當(dāng)A收到這個(gè)重傳的FIN=1, 最大時(shí)間剛好是2MSL(A發(fā)送最后的ACK時(shí)間 + B重傳FIN=1的時(shí)間)當(dāng)A收到B的FIN=1時(shí)候,再次發(fā)送最后的ACK,同事2MSL計(jì)時(shí)器重新啟動(dòng)
2.可能這時(shí)候還有很多從B發(fā)過來的報(bào)文(因?yàn)閾矶?,或排?duì)超時(shí),被重傳的那些報(bào)文)還在來的路上,但是這些報(bào)文已經(jīng)無效了,為了防止A機(jī)器上新的連接收到這些報(bào)文,需要等這次報(bào)文超時(shí)。
TCP有限狀態(tài)機(jī)

- 粗實(shí)線對(duì)應(yīng)主動(dòng)打開連接一方的狀態(tài)變化
- 虛線對(duì)應(yīng)被動(dòng)打開連接一方的狀態(tài)變化