C++網(wǎng)絡(luò)編程之TCP協(xié)議

概述

TCP,即傳輸控制協(xié)議,英文全稱為Transmission Control Protocol,是互聯(lián)網(wǎng)協(xié)議套件中的核心協(xié)議之一。它工作在OSI七層模型的傳輸層,也工作在TCP/IP四層模型的傳輸層。TCP協(xié)議的主要目的是:在不可靠的網(wǎng)絡(luò)環(huán)境中提供可靠的、面向連接的、基于字節(jié)流的傳輸服務(wù)。
TCP協(xié)議主要具有以下五個(gè)特點(diǎn)。
1、面向連接。TCP在數(shù)據(jù)傳輸之前,必須先建立連接。這種連接是通過三次握手過程建立的,確保雙方都已準(zhǔn)備好進(jìn)行數(shù)據(jù)傳輸。
2、可靠性。TCP通過一系列機(jī)制來確保數(shù)據(jù)的可靠傳輸,包括:序列號、確認(rèn)應(yīng)答、超時(shí)重傳、流量控制和擁塞控制等。如果數(shù)據(jù)在傳輸過程中丟失或出錯(cuò),TCP會重新發(fā)送數(shù)據(jù),直到接收方成功接收為止。
3、有序性。TCP保證數(shù)據(jù)按照發(fā)送的順序到達(dá)接收方,即使在網(wǎng)絡(luò)中數(shù)據(jù)包的到達(dá)順序可能被打亂。
4、基于字節(jié)流。TCP將應(yīng)用程序發(fā)送的數(shù)據(jù)視為一個(gè)無結(jié)構(gòu)的字節(jié)流,而不是一系列的消息。TCP負(fù)責(zé)將字節(jié)流分割成適當(dāng)大小的段,并在接收端重新組合成字節(jié)流。
5、全雙工通信。TCP連接允許雙方同時(shí)發(fā)送和接收數(shù)據(jù),即通信是雙向的。

報(bào)文格式

TCP的報(bào)文包括兩個(gè)部分:報(bào)文頭和數(shù)據(jù)。報(bào)文頭又分為固定部分和選項(xiàng)部分。報(bào)文頭固定部分為20個(gè)字節(jié),各個(gè)字段的含義如下。
1、源端口號:2字節(jié),標(biāo)識發(fā)送方的應(yīng)用程序端口。
2、目的端口號:2字節(jié),標(biāo)識接收方的應(yīng)用程序端口。
3、序列號:4字節(jié),標(biāo)識從TCP源端向目的端發(fā)送的數(shù)據(jù)字節(jié)流的起始字節(jié)的序列號。
4、確認(rèn)號:4字節(jié),只有在ACK標(biāo)志位為1時(shí)才有效,表示下一個(gè)期望接收到的字節(jié)的序列號。如果確認(rèn)號為n,則表示接收方已經(jīng)成功接收到了所有序列號小于n的數(shù)據(jù)。如果在規(guī)定時(shí)間內(nèi)沒有收到確認(rèn)信息,發(fā)送方將重新發(fā)送報(bào)文段,以防止由于網(wǎng)絡(luò)問題導(dǎo)致的數(shù)據(jù)丟失。
5、數(shù)據(jù)偏移:也稱為報(bào)頭長度,占用4位,表示TCP報(bào)頭長度(以4字節(jié)為單位),因?yàn)門CP報(bào)頭可以包含可選的選項(xiàng)部分。
6、保留:6位,必須置0。
7、標(biāo)志位:6位,每個(gè)標(biāo)志位都有其特定的功能,具體含義如下。
(1)URG:緊急指針有效。
(2)ACK:確認(rèn)號有效。
(3)PSH:推送數(shù)據(jù)到接收應(yīng)用程序。
(4)RST:重置TCP連接。
(5)SYN:在連接建立時(shí)同步序列號。
(6)FIN:沒有更多數(shù)據(jù)從應(yīng)用程序發(fā)送。
8、窗口大小:2字節(jié),指定發(fā)送方可接收的數(shù)據(jù)量。
9、校驗(yàn)和:2字節(jié),用于檢測數(shù)據(jù)包中的錯(cuò)誤。
10、緊急指針:2字節(jié),只有當(dāng)URG標(biāo)志被設(shè)置時(shí)才有意義,指出緊急數(shù)據(jù)的最后一個(gè)字節(jié)相對于序列號的位置。
報(bào)文頭選項(xiàng)部分包含一些可選的信息,比如:最大報(bào)文長度、窗口擴(kuò)大因子、時(shí)間戳等,用于實(shí)現(xiàn)除TCP報(bào)文段頭部指定功能外的擴(kuò)展功能。報(bào)文頭選項(xiàng)部分最長為40個(gè)字節(jié),因此,TCP報(bào)文頭最長可達(dá)60個(gè)字節(jié)。
報(bào)文頭之后便是數(shù)據(jù)部分,這部分包含了從應(yīng)用程序來的實(shí)際數(shù)據(jù)。數(shù)據(jù)的長度可變,并且它的長度加上TCP報(bào)文頭的長度,應(yīng)該等于整個(gè)TCP報(bào)文段的長度。

三次握手

TCP協(xié)議通過三次握手的過程來建立一個(gè)連接,這一過程確保雙方都準(zhǔn)備好進(jìn)行數(shù)據(jù)交換,并協(xié)商了一些必要的參數(shù)。三次握手的詳細(xì)步驟如下。
第一次握手(SYN):客戶端向服務(wù)器發(fā)送一個(gè)SYN(同步序列號)報(bào)文段,這個(gè)報(bào)文段中包含了一個(gè)初始序列號,這個(gè)序列號用于后續(xù)的數(shù)據(jù)傳輸。同時(shí),SYN標(biāo)志位置1。報(bào)文段格式為:SYN = 1、序列號 = x。
第二次握手(SYN-ACK):服務(wù)器接收到客戶端的SYN報(bào)文段后,如果同意建立連接,就會回應(yīng)一個(gè)SYN-ACK報(bào)文段。這個(gè)報(bào)文段中也包含了一個(gè)新的序列號以及對客戶端序列號的確認(rèn)(ACK),確認(rèn)號是客戶端序列號加1。報(bào)文段格式為:SYN = 1、ACK = 1、序列號 = y、確認(rèn)號 = x + 1。
第三次握手(ACK):客戶端接收到服務(wù)器的SYN-ACK報(bào)文段后,會發(fā)送一個(gè)ACK報(bào)文段作為應(yīng)答。這個(gè)ACK報(bào)文段的確認(rèn)號是服務(wù)器序列號加1,表明客戶端已經(jīng)收到了服務(wù)器的序列號。報(bào)文段格式為:ACK = 1、序列號 = x + 1、確認(rèn)號 = y + 1。
至此,三次握手完成,TCP連接建立成功,雙方現(xiàn)在可以開始交換數(shù)據(jù)了。每個(gè)方向上的數(shù)據(jù)流都使用自己的序列號和確認(rèn)號來跟蹤數(shù)據(jù)包的狀態(tài),這樣就可以確保數(shù)據(jù)按照正確的順序到達(dá)目的地,并且可以檢測出丟失或重復(fù)的數(shù)據(jù)包。
為了更加形象地理解TCP協(xié)議三次握手的過程,可以參考下面的時(shí)序圖。


111.png

四次揮手

TCP協(xié)議的四次揮手是指在TCP連接的終止過程中,所進(jìn)行的一系列交互。這一過程是為了確保所有已發(fā)送的數(shù)據(jù)都被正確接收,并安全地?cái)嚅_連接。四次揮手的詳細(xì)步驟如下。
第一次揮手(FIN):發(fā)起方(通常是客戶端)發(fā)送一個(gè)FIN(結(jié)束)報(bào)文段,告訴對方自己已經(jīng)沒有數(shù)據(jù)要發(fā)送了,希望關(guān)閉連接。這個(gè)報(bào)文段包含一個(gè)FIN標(biāo)志位被設(shè)置,以及一個(gè)序列號。報(bào)文段格式為:FIN = 1、序列號 = x。
第二次揮手(ACK):接收方(通常是服務(wù)器)接收到FIN報(bào)文段后,發(fā)送一個(gè)ACK報(bào)文段作為應(yīng)答。這個(gè)ACK報(bào)文段的確認(rèn)號是發(fā)起方序列號加1,表明接收方已經(jīng)收到了發(fā)起方的FIN報(bào)文段。報(bào)文段格式為:ACK = 1、序列號 = y、確認(rèn)號 = x + 1。此時(shí),發(fā)起方到接收方的方向上已經(jīng)完成了關(guān)閉,接收方仍然可以向發(fā)起方發(fā)送數(shù)據(jù)。接收方在發(fā)送完所有數(shù)據(jù)后,才會繼續(xù)后續(xù)的步驟。
第三次揮手(FIN):當(dāng)接收方也沒有數(shù)據(jù)要發(fā)送時(shí),它也會發(fā)送一個(gè)FIN報(bào)文段給發(fā)起方,表示自己也完成了數(shù)據(jù)發(fā)送,希望關(guān)閉連接。報(bào)文段格式為:FIN = 1、ACK = 1、序列號 = z、確認(rèn)號 = x + 1。
第四次揮手(ACK):發(fā)起方接收到接收方的FIN報(bào)文段后,發(fā)送一個(gè)ACK報(bào)文段作為應(yīng)答。這個(gè)ACK報(bào)文段的確認(rèn)號是接收方序列號加1,表明發(fā)起方已經(jīng)收到了接收方的FIN報(bào)文段。報(bào)文段格式為:ACK = 1、序列號 = x + 1、確認(rèn)號 = z + 1。
至此,連接正式關(guān)閉,雙方都不再發(fā)送數(shù)據(jù)。需要注意的是,在最后一次揮手之后,發(fā)起方和接收方都會進(jìn)入TIME_WAIT狀態(tài)和CLOSE_WAIT狀態(tài)一段時(shí)間,以確保所有的數(shù)據(jù)包都被正確接收,并且沒有遲到的數(shù)據(jù)包。在這段時(shí)間過后,連接將完全關(guān)閉。通過四次揮手的過程,TCP確保了在斷開連接之前所有數(shù)據(jù)都被正確接收,從而維持了連接的可靠性。
為了更加形象地理解TCP協(xié)議四次揮手的過程,可以參考下面的時(shí)序圖。


222.png

數(shù)據(jù)傳輸

TCP協(xié)議的數(shù)據(jù)傳輸過程是一個(gè)復(fù)雜的機(jī)制,它不僅保證了數(shù)據(jù)的可靠傳輸,還提供了流量控制、擁塞控制等功能。在三次握手建立連接之后、四次揮手關(guān)閉連接之前,TCP會進(jìn)行數(shù)據(jù)的雙向傳輸。雙向傳輸過程中涉及到的一些重要機(jī)制和概念包括:數(shù)據(jù)分割與重組、流量控制、擁塞控制、確認(rèn)應(yīng)答、重傳機(jī)制、錯(cuò)誤檢測等。下面,分別進(jìn)行介紹。
1、數(shù)據(jù)分割與重組。當(dāng)應(yīng)用程序?qū)?shù)據(jù)傳遞給TCP時(shí),TCP會根據(jù)最大報(bào)文段長度MSS來決定如何將數(shù)據(jù)分割成多個(gè)TCP報(bào)文段。每個(gè)報(bào)文段都包含一個(gè)序列號,該序列號標(biāo)識了這個(gè)報(bào)文段中第一個(gè)字節(jié)在整個(gè)數(shù)據(jù)流中的位置。接收端根據(jù)接收到的報(bào)文段中的序列號將數(shù)據(jù)重新組裝起來,以確保數(shù)據(jù)按照發(fā)送順序正確地重組。
2、流量控制。TCP通過滑動(dòng)窗口機(jī)制來進(jìn)行流量控制,避免發(fā)送方發(fā)送數(shù)據(jù)過快導(dǎo)致接收方來不及處理。接收方會在其ACK報(bào)文中告訴發(fā)送方當(dāng)前可以接收的最大數(shù)據(jù)量(即窗口大小),發(fā)送方只能發(fā)送不超過這個(gè)窗口大小的數(shù)據(jù)。隨著接收方處理能力的變化,接收窗口的大小會動(dòng)態(tài)調(diào)整,以適應(yīng)不同的網(wǎng)絡(luò)狀況。
3、擁塞控制。為了防止網(wǎng)絡(luò)擁塞,TCP實(shí)現(xiàn)了一系列的擁塞控制算法,比如:慢啟動(dòng)、擁塞避免、快速重傳和快速恢復(fù)等。
(1)慢啟動(dòng)。當(dāng)連接剛剛建立或發(fā)生超時(shí)重傳時(shí),TCP采用慢啟動(dòng)策略,逐漸增加發(fā)送速率,直到達(dá)到某個(gè)閾值或出現(xiàn)丟包。
(2)擁塞避免。一旦進(jìn)入穩(wěn)定狀態(tài),TCP會使用擁塞避免算法來維持一個(gè)相對穩(wěn)定的發(fā)送速率,同時(shí)監(jiān)測網(wǎng)絡(luò)擁塞情況。
(3)快速重傳。如果發(fā)送方連續(xù)收到相同的ACK,則認(rèn)為有報(bào)文丟失,并立即重傳該報(bào)文,而不等待超時(shí)定時(shí)器到期。
(4)快速恢復(fù)。在快速重傳后,TCP進(jìn)入快速恢復(fù)階段,繼續(xù)調(diào)整發(fā)送速率,直到網(wǎng)絡(luò)狀況恢復(fù)正常。
4、確認(rèn)應(yīng)答。當(dāng)接收方正確地接收到一個(gè)TCP報(bào)文段后,它會發(fā)送一個(gè)ACK報(bào)文段給發(fā)送方。這個(gè)ACK報(bào)文段中包含了確認(rèn)號,該號碼是期望接收的下一個(gè)字節(jié)的序列號。比如:如果接收方收到了序列號為100到200的數(shù)據(jù),那么ACK報(bào)文段中的確認(rèn)號將是201,表示“我已經(jīng)收到了直到200為止的所有數(shù)據(jù),接下來請發(fā)送從201開始的數(shù)據(jù)”。
5、重傳機(jī)制。TCP為每個(gè)報(bào)文段設(shè)置了一個(gè)重傳計(jì)時(shí)器,如果在這個(gè)時(shí)間內(nèi)沒有收到相應(yīng)的ACK,就認(rèn)為報(bào)文段丟失并重發(fā)。如果發(fā)送方收到連續(xù)的重復(fù)ACK,則可能意味著某個(gè)報(bào)文段丟失或延遲,此時(shí)發(fā)送方會提前重傳丟失的報(bào)文段。
6、錯(cuò)誤檢測。每個(gè)TCP報(bào)文段都包含一個(gè)校驗(yàn)和字段,用于檢測傳輸過程中可能出現(xiàn)的數(shù)據(jù)損壞。如果計(jì)算出的校驗(yàn)和與接收到的不匹配,報(bào)文段會被丟棄,并要求重傳。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,807評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內(nèi)容