TCP協(xié)議

??TCP協(xié)議是TCP/IP體系中非常復(fù)雜也是非常重要的協(xié)議,所以后面也會(huì)有更多的文章介紹該協(xié)議奕塑。
本文內(nèi)容

1 TCP特點(diǎn)

??(1) TCP 是面向連接的傳輸層協(xié)議柬赐。

應(yīng)用程序是使用TCP協(xié)議之前斑响,必須建立TCP連接凰慈。在傳送數(shù)據(jù)完畢后汞幢,必須釋放已建立的TCP連接。TCP連接是一條虛連接(邏輯連接)微谓,而不是一條真正的物理連接森篷。

??(2) 每一條TCP連接只能有兩個(gè)端點(diǎn)输钩,每條TCP連接只能是點(diǎn)對(duì)點(diǎn)的(一對(duì)一)。

??(3) TCP提供可靠交付的服務(wù)仲智。通過(guò)TCP連接傳送的數(shù)據(jù)买乃,無(wú)差錯(cuò)、不丟失钓辆、不重復(fù)剪验、并且按序達(dá)到

??(4) TCP提供全雙工通信岩馍。

TCP允許通信雙方的應(yīng)用進(jìn)程在任何時(shí)候都能發(fā)送數(shù)據(jù)碉咆。TCP連接的兩端都設(shè)有發(fā)送緩存接收緩存抖韩,用來(lái)臨時(shí)存放雙方通信的數(shù)據(jù)蛀恩。

??1) 發(fā)送緩存:用于存放準(zhǔn)備發(fā)送的數(shù)據(jù)已發(fā)送但尚未收到確認(rèn)的數(shù)據(jù)(因?yàn)門CP提供可靠交付服務(wù),對(duì)于發(fā)送的數(shù)據(jù)必須要收到接收方的確認(rèn)回復(fù)茂浮,如果數(shù)據(jù)丟失了双谆,就可以從發(fā)送緩存中將剛發(fā)送的數(shù)據(jù)再發(fā)送一次,直到收到確認(rèn)回復(fù)后席揽,才會(huì)將這個(gè)數(shù)據(jù)從緩存中刪除)顽馋。
??2) 接收緩存:用于存放按序到達(dá)但尚未被接收應(yīng)用程序讀取的數(shù)據(jù)不按序達(dá)到的數(shù)據(jù)

??(5) TCP面向字節(jié)流幌羞。流是指流入進(jìn)程或從進(jìn)程流出的字節(jié)序列寸谜。

雖然應(yīng)用程序和TCP的交互是一次一個(gè)數(shù)據(jù)塊(大小可以不等),但是TCP把應(yīng)用程序交下來(lái)的數(shù)據(jù)塊看成僅僅一連串的無(wú)結(jié)構(gòu)的字節(jié)流属桦。

??如下圖所示熊痴,假如發(fā)送方要發(fā)送一個(gè)文件,會(huì)將這個(gè)文件按字節(jié)排序并編號(hào)聂宾,在發(fā)送時(shí)將這些字節(jié)放入TCP緩存中果善,從緩存中取出若干字節(jié)(可以不等)并加上TCP首部形成一個(gè)完整的報(bào)文段在鏈路上傳送,最終到達(dá)接收方的TCP緩存中系谐。

TCP并不關(guān)心應(yīng)用進(jìn)程依次把多長(zhǎng)的報(bào)文發(fā)送到TCP緩存中巾陕,而是根據(jù)接收方和當(dāng)前網(wǎng)絡(luò)擁塞的程度來(lái)決定一個(gè)報(bào)文段應(yīng)包含多少個(gè)字節(jié)。所以如果應(yīng)用進(jìn)程傳送到TCP緩存中的數(shù)據(jù)塊太長(zhǎng)纪他,TCP就可以把它劃分短一些再傳送鄙煤,而UDP是面向報(bào)文的,應(yīng)用進(jìn)程給出的數(shù)據(jù)塊UDP就是按照給出的長(zhǎng)度發(fā)送茶袒。

2 TCP的連接

??每條TCP連接有兩個(gè)端點(diǎn)馆类,TCP連接的端點(diǎn)叫做套接字(socket)或插口,這里的套接字定義為:端口號(hào)拼接到IP地址即構(gòu)成了套接字弹谁。
??套接字的表示方法是在點(diǎn)分十進(jìn)制的IP地址后面寫上端口號(hào)乾巧,中間用冒號(hào)或逗號(hào)隔開句喜。

套接字 socket = (IP地址 : 端口號(hào))

例如,若IP地址為192.3.4.5沟于,端口號(hào)是80咳胃,那么得到的套接字就是(192.3.4.5:80)
??每條TCP連接唯一地被通信的兩個(gè)端點(diǎn)(即兩個(gè)套接字確定)所確定。即:

TCP連接 = {socket1,socket2} = {(IP1 : prot1),(IP2 : prot2)}

3 TCP報(bào)文段的首部格式

??一個(gè)TCP報(bào)文段分為首部數(shù)據(jù)部分兩部分旷太。


??TCP報(bào)文段首部的前20個(gè)字節(jié)是固定的展懈,后面有4nn是整數(shù))字節(jié)是根據(jù)需要而增加的選項(xiàng)。因此TCP首部的最小字節(jié)是20字節(jié)供璧。

??(1) 源端口和目的端口:各占2自己存崖,分別寫入源端口號(hào)和目的端口號(hào),TCP的分用功能也是通過(guò)端口實(shí)現(xiàn)的睡毒。

??(2) 序號(hào):占4字節(jié)来惧,序號(hào)范圍是[ 0 , 232 - 1],共 232個(gè)序號(hào)演顾。TCP是面向字節(jié)流的供搀,在一個(gè)TCP連接中傳送的字節(jié)流中的每一個(gè)字節(jié)都是按順序編號(hào)。首部中的序號(hào)字段值則指的是本報(bào)文段所發(fā)送的數(shù)據(jù)的第一字節(jié)的序號(hào)钠至。

序號(hào)是可以重用的葛虐,當(dāng)序號(hào)增加到 232 - 1后,下一個(gè)序號(hào)就又回到了0棉钧,所以序號(hào)邏輯上可以表示為一個(gè)循環(huán)數(shù)組屿脐。

例如,若一個(gè)報(bào)文段的序號(hào)字段值是301宪卿,而攜帶的數(shù)據(jù)共有100字節(jié)的诵,這就表明:本報(bào)文段的數(shù)據(jù)第一個(gè)字節(jié)的序號(hào)是301,最后一個(gè)字節(jié)的序號(hào)是400愧捕。如果還有下一個(gè)報(bào)文段奢驯,則其序號(hào)字段的的值應(yīng)為401。

??(3) 確認(rèn)號(hào):占4字節(jié)次绘,是期望收到對(duì)方下一個(gè)報(bào)文段的第一個(gè)數(shù)據(jù)字節(jié)的序號(hào)瘪阁。

例如,B正確收到了A發(fā)送過(guò)來(lái)的一個(gè)報(bào)文段邮偎,其序號(hào)字段值是501管跺,而該報(bào)文段的數(shù)據(jù)長(zhǎng)度是200字節(jié)(序號(hào)501~700),這表明B正確收到了A發(fā)送的到序號(hào)700為止的數(shù)據(jù)禾进,因此B期望收到A的下一個(gè)數(shù)據(jù)序號(hào)是701豁跑,TCP是可靠傳輸,收到數(shù)據(jù)后需要給發(fā)送方回復(fù)確認(rèn)信息泻云,所以B在收到數(shù)據(jù)后給A發(fā)送的確認(rèn)收到的報(bào)文段中就把確認(rèn)號(hào)置為701艇拍。

若確認(rèn)號(hào) = N,則表明:到序號(hào)N - 1為止的所有數(shù)據(jù)都已正確收到狐蜕。

??(4) 數(shù)據(jù)偏移:占4位,單位:4B卸夕。它指出TCP報(bào)文段數(shù)據(jù)起始處距離TCP報(bào)文段的起始處有多遠(yuǎn)层释。這個(gè)字段實(shí)際上是指出TCP報(bào)文段的首部長(zhǎng)度

如上圖所示快集,如果數(shù)據(jù)偏移字段的值為:1101(十進(jìn)制13)贡羔,所以數(shù)據(jù)偏移的值為13 × 4B = 42B,所以可知TCP報(bào)文段數(shù)據(jù)部分的起始處到TCP報(bào)文段的起始處(即TCP首部的)

數(shù)據(jù)偏移占4位个初,最大值為1111乖寒,即15,即數(shù)據(jù)偏移的值最大為60字節(jié)(TCP首部最大長(zhǎng)度為60字節(jié))院溺,又TCP首部有固定的20字節(jié)楣嘁,所以TCP可選字段的長(zhǎng)度不能超過(guò)40字節(jié)。

??(5) 保留:占6位覆获,保留今后使用马澈。

??接下來(lái)是6個(gè)控制位
??(6) 緊急URG(URGent):僅當(dāng)URG = 1瓢省,表明后面的緊急指針字段才有效弄息。它表明系統(tǒng)此報(bào)文段有緊急數(shù)據(jù),應(yīng)盡快傳送(相當(dāng)于高優(yōu)先級(jí)數(shù)據(jù))勤婚,而不要按照原來(lái)的排隊(duì)順序來(lái)傳送摹量。

??前面說(shuō)到,在發(fā)送報(bào)文段時(shí)馒胆,需要將字節(jié)先存放在TCP緩存中缨称,如果發(fā)送應(yīng)用需要發(fā)送一個(gè)緊急指令,如中斷指令(Control + C)祝迂,如果不使用緊急數(shù)據(jù)睦尽,那么這兩個(gè)字符就存在TCP緩存的末尾,直到前面的數(shù)據(jù)處理完才將這兩個(gè)字符交給接收方型雳。
??當(dāng)URG = 1時(shí)当凡,發(fā)送應(yīng)用進(jìn)程就告訴發(fā)送方的TCP有緊急數(shù)據(jù)要傳送,于是發(fā)送方TCP就把緊急數(shù)據(jù)插入到本報(bào)文段數(shù)據(jù)的最前面纠俭,而在緊急數(shù)據(jù)之后的數(shù)據(jù)仍是普通數(shù)據(jù)沿量。

??(7) 確認(rèn)ACK(ACKnowledgment):僅當(dāng)ACK = 1時(shí)確認(rèn)號(hào)字段才有效。TCP規(guī)定冤荆,在連接建立后所有傳送的報(bào)文段都必須把ACK置1朴则。

??(8) 推送PSH(PuSH):通常如果TCP緩存中字節(jié)很少,TCP會(huì)等待積累有足夠多的字節(jié)后再構(gòu)成報(bào)文段發(fā)送出去钓简,當(dāng)發(fā)送方將 PSH 置為 1時(shí)乌妒,并立即創(chuàng)建一個(gè)報(bào)文段發(fā)送出去汹想,接收方TCP收到PSH = 1的報(bào)文段,就盡快地交付接收應(yīng)用進(jìn)程撤蚊,而不再等到整個(gè)緩存都填滿在向上交付欧宜。

這個(gè)字段適合在交互式的通信,在一端應(yīng)用進(jìn)程鍵入一個(gè)命令立即能夠收到對(duì)方的響應(yīng)拴魄,但是這種推送操作很少使用冗茸。

??(9) 復(fù)位RST(ReSeT):當(dāng)RST = 1時(shí),表明TCP連接中出現(xiàn)了嚴(yán)重差錯(cuò)匹中,必須釋放連接夏漱,然后再重新建立傳輸連接。RST置為1還可以用來(lái)拒絕一個(gè)非法的報(bào)文段或拒絕打開一個(gè)連接顶捷。RST也可稱為重建位或重置位挂绰。

??(10) 同步SYN(SYNchronization):在連接建立時(shí)用來(lái)同步序號(hào)。當(dāng)SYN = 1而ACK = 0時(shí)服赎,表明這是一個(gè)連接請(qǐng)求報(bào)文段葵蒂。對(duì)方同意建立連接,則應(yīng)在響應(yīng)的報(bào)文段中使用SYN = 1和ACK = 1.因此重虑,SYN 置為1表示這是一個(gè)連接請(qǐng)求或連接接收?qǐng)?bào)文践付。

??(11) 終止FIN(FINis):用來(lái)釋放一個(gè)連接。當(dāng)FIN = 1時(shí)缺厉,表明此報(bào)文段的發(fā)送方的數(shù)據(jù)發(fā)送完畢永高,并要求釋放傳輸連接。

??(12) 窗口:占2字節(jié)提针,是指發(fā)送本報(bào)文段的一方的接收窗口命爬。窗口的值表示:從本報(bào)文段首部中的確認(rèn)號(hào)算起,接收方目前允許對(duì)方發(fā)送的數(shù)據(jù)量辐脖。即窗口值作為接收方讓發(fā)送方設(shè)置其發(fā)送窗口的依據(jù)饲宛。之所以要有這個(gè)限制,是因?yàn)榻邮辗降臄?shù)據(jù)緩存空間是有限的嗜价。

例如艇抠,A是發(fā)送方,B是接收方炭剪,B給A發(fā)送一個(gè)確認(rèn)接收數(shù)據(jù)的報(bào)文练链,其確認(rèn)號(hào)701(表示701之前的所有數(shù)據(jù)都已經(jīng)正確收到,期望A下一個(gè)報(bào)文段的第一個(gè)數(shù)據(jù)字節(jié)序號(hào)為701)奴拦,窗口字段的值是1000媒鼓,這就是告訴發(fā)送方A:從701號(hào)算起,我的接收緩存還可以接收1000個(gè)字節(jié)數(shù)據(jù),在你給我發(fā)送數(shù)據(jù)的時(shí)候绿鸣,你需要考慮一下我的接收能力疚沐。

窗口字段明確指出了現(xiàn)在允許對(duì)方發(fā)送的數(shù)據(jù)量。窗口值是經(jīng)常在動(dòng)態(tài)變化潮模。

??(13) 校驗(yàn)和:占2字節(jié)亮蛔。校驗(yàn)和字段校驗(yàn)的范圍包括首部數(shù)據(jù)這兩個(gè)部分。和UDP用戶數(shù)據(jù)報(bào)一樣擎厢,在計(jì)算校驗(yàn)和時(shí)究流,需要在TCP報(bào)文段的前面加上12字節(jié)的偽首部。偽首部的格式和UDP偽首部的格式一樣动遭,只是需要將協(xié)議字段改為6芬探,TCP協(xié)議號(hào)是6。

??(14) 緊急指針:緊急指針只有在URG= 1時(shí)才有意義厘惦,它和URG字段配合使用偷仿,它指出了報(bào)文段中緊急數(shù)據(jù)的字節(jié)數(shù),因此宵蕉,緊急指針指出了緊急數(shù)據(jù)的末尾在報(bào)文段中的位置酝静。

即使窗口的值為0也可以發(fā)送緊急數(shù)據(jù)。

??(15) 選項(xiàng)和填充:長(zhǎng)度可變羡玛,最長(zhǎng)可達(dá)40字節(jié)别智。填充字段是為了使整個(gè)TCP首部的長(zhǎng)度是4字節(jié)的整數(shù)倍。

4 幾個(gè)選項(xiàng)字段

??(1) 最大報(bào)文段長(zhǎng)度MSS(Maximum Segment Size):是指每個(gè)TCP報(bào)文段中數(shù)據(jù)字段的最大長(zhǎng)度缝左,即TCP報(bào)文段長(zhǎng)度減去TCP首部長(zhǎng)度亿遂。它是為了考慮網(wǎng)絡(luò)利用率浓若。

??TCP報(bào)文段的數(shù)據(jù)部分渺杉,需要加上TCP首部至少20個(gè)字節(jié)(即沒(méi)有可變部分)和IP首部至少20字節(jié)才能組成一個(gè)IP數(shù)據(jù)報(bào)。若選擇較小的MSS長(zhǎng)度挪钓,例如是越,MSS是1,即TCP報(bào)文段數(shù)據(jù)部分長(zhǎng)度為1個(gè)字節(jié)碌上,那么IP層傳輸?shù)臄?shù)據(jù)報(bào)的開銷至少有40個(gè)字節(jié)倚评,這就導(dǎo)致網(wǎng)絡(luò)的利用率降低。
??反之馏予,如果MSS非常大天梧,那么在IP層傳輸時(shí)就需要分片,在終點(diǎn)時(shí)需要將收到的各個(gè)分片重新組裝成原來(lái)的TCP報(bào)文段霞丧,這樣也會(huì)使網(wǎng)絡(luò)開銷變大呢岗。
??因此,MSS應(yīng)盡可能大些,只要在IP層輸層傳輸時(shí)不需要分片就行后豫。默認(rèn)值是536字節(jié)長(zhǎng)悉尾,因此所有在互聯(lián)網(wǎng)上的主機(jī)都應(yīng)能接受的報(bào)文段長(zhǎng)度是536 + 20 = 556字節(jié)。

??(2) 窗口擴(kuò)大:占3字節(jié)挫酿,這個(gè)選項(xiàng)是為了擴(kuò)大窗口构眯。TCP首部的窗口字段長(zhǎng)度是16位,因此最大的窗口大小是64K字節(jié)早龟,窗口擴(kuò)大中有一個(gè)字節(jié)表示移位值S惫霸。新的窗口值等于TCP首部中的窗口位數(shù)從16增加到(16 + S)。移位值允許使用的最大值是14葱弟,相當(dāng)于窗口最大值增加到2(16+14) - 1它褪。

窗口擴(kuò)大選項(xiàng)在雙方初始建立TCP連接時(shí)進(jìn)行協(xié)商,如果某一端實(shí)現(xiàn)了窗口擴(kuò)大翘悉,當(dāng)它不需要擴(kuò)大其窗口時(shí)茫打,可發(fā)送S = 0的選項(xiàng),使窗口大小回到16妖混。

??(3) 時(shí)間戳:占10字節(jié)老赤,其中最主要的是時(shí)間戳值字段(4字節(jié))和時(shí)間戳回送回答字段(4字節(jié))。時(shí)間戳選項(xiàng)有以下兩個(gè)功能:

??1) 計(jì)算往返時(shí)間RTT制市。發(fā)送方在報(bào)文段時(shí)把當(dāng)前時(shí)鐘的時(shí)間值放入時(shí)間戳字段抬旺,接收方在確認(rèn)該報(bào)文段時(shí)把時(shí)間戳字段復(fù)制到時(shí)間戳回送回答字段。因此祥楣,發(fā)送方在接收到確認(rèn)報(bào)文后开财,就可以準(zhǔn)確的計(jì)算出RTT來(lái)。
??2) 用于處理TCP序號(hào)超過(guò)232的情況误褪,這又稱為防止序號(hào)繞回PAWS(Protect Against Wrapped Sequence numbers)责鳍,后面再介紹。

5 小結(jié)

??本文完

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兽间,一起剝皮案震驚了整個(gè)濱河市历葛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘀略,老刑警劉巖恤溶,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異帜羊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)讼育,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門帐姻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)粮宛,“玉大人,你說(shuō)我怎么就攤上這事卖宠∥¤荆” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵扛伍,是天一觀的道長(zhǎng)筷畦。 經(jīng)常有香客問(wèn)我,道長(zhǎng)刺洒,這世上最難降的妖魔是什么鳖宾? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮逆航,結(jié)果婚禮上鼎文,老公的妹妹穿的比我還像新娘。我一直安慰自己因俐,他們只是感情好拇惋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抹剩,像睡著了一般撑帖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上澳眷,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天胡嘿,我揣著相機(jī)與錄音,去河邊找鬼钳踊。 笑死衷敌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拓瞪。 我是一名探鬼主播缴罗,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吴藻!你這毒婦竟也來(lái)了瞒爬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤沟堡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后矢空,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航罗,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年屁药,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粥血。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖复亏,靈堂內(nèi)的尸體忽然破棺而出趾娃,到底是詐尸還是另有隱情,我是刑警寧澤缔御,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布抬闷,位于F島的核電站,受9級(jí)特大地震影響耕突,放射性物質(zhì)發(fā)生泄漏笤成。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一眷茁、第九天 我趴在偏房一處隱蔽的房頂上張望炕泳。 院中可真熱鬧,春花似錦上祈、人聲如沸培遵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荤懂。三九已至,卻和暖如春塘砸,著一層夾襖步出監(jiān)牢的瞬間节仿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工掉蔬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留廊宪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓女轿,卻偏偏與公主長(zhǎng)得像箭启,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛉迹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354