TCP/IP詳解 018 TCP的連接與終止

因?yàn)門CP是一個(gè)面向連接的協(xié)議充易。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前菇民,都必須先在雙方之間建立一條連接禁筏。

連接的建立與終止

TCP的三次握手
1持钉、請(qǐng)求端發(fā)送一個(gè)SYN段指明客戶打算連接的服務(wù)器的端口,以及初始序號(hào)(ISN篱昔,在這個(gè)例子中位1415531521)每强。這個(gè)SYN段為報(bào)文段1
2、服務(wù)器發(fā)回包含服務(wù)器的初始序號(hào)的SYN報(bào)文段(報(bào)文段2)作為應(yīng)答州刽,同時(shí)空执,將確認(rèn)序號(hào)設(shè)置為客戶的ISN加1以對(duì)客戶的SYN報(bào)文段進(jìn)行確認(rèn),一個(gè)SYN將占用一個(gè)序號(hào)
3穗椅、客戶必須將確認(rèn)序號(hào)設(shè)置為服務(wù)器的ISN加1以對(duì)服務(wù)器的SYN報(bào)文段進(jìn)行確認(rèn)(報(bào)文段3)


image.png

發(fā)送第一個(gè)SYN的一端將執(zhí)行主動(dòng)打開(active open)辨绊,接收這個(gè)SYN并發(fā)回下一個(gè)SYN的另一端執(zhí)行被動(dòng)打開(passive open)
當(dāng)一端為建立連接而發(fā)送它的SYN時(shí),它為連接選擇一個(gè)初始序號(hào)匹表,ISN隨時(shí)間而變化门坷,因此每個(gè)連接都將具有不同的ISN。
RFC 793指出 ISN可看作是一個(gè)32比特的計(jì)數(shù)器袍镀,每4ms加1默蚌,這樣選序號(hào)的目的在于防止在網(wǎng)絡(luò)中被延遲的分組在以后又被傳送,而導(dǎo)致某個(gè)連接的一方對(duì)它作錯(cuò)誤的解釋苇羡。

image.png

連接終止協(xié)議

終止一個(gè)連接需要經(jīng)過(guò)4次握手
由TCP的半關(guān)閉(half-close)造成的敏簿。以為一個(gè)TCP連接是全雙工(即數(shù)據(jù)在兩個(gè)方向上能同時(shí)傳遞),因此每個(gè)方向必須單獨(dú)地進(jìn)行關(guān)閉宣虾。
這原則就是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向連接,當(dāng)一端收到一個(gè)FIN温数,它必須通知應(yīng)用層另一端已經(jīng)終止了那個(gè)方向的數(shù)據(jù)傳送绣硝。
收到一個(gè)FIN只意味著在這一方向上沒有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后扔能發(fā)送數(shù)據(jù)撑刺。
正常關(guān)閉的流程:

image.png

首先進(jìn)行關(guān)閉的一方(即發(fā)送第一個(gè)FIN)將執(zhí)行主動(dòng)關(guān)閉鹉胖,而另一方(收到這個(gè)FIN)執(zhí)行被動(dòng)關(guān)閉,通常一方完成主動(dòng)關(guān)閉而另一方完成被動(dòng)關(guān)閉。
下圖是一個(gè)終止一個(gè)連接的典型握手順序
image.png

連接通常是由客戶端發(fā)起的甫菠,這樣第一個(gè)SYN從客戶傳到服務(wù)器挠铲,每一端都能主動(dòng)關(guān)閉這個(gè)連接(即首先發(fā)送FIN)。然而寂诱,一般由客戶端決定何時(shí)終止連接拂苹,因?yàn)榭蛻暨M(jìn)程通常由用戶交互控制,用戶會(huì)鍵入諸如“quit”一樣的命令來(lái)終止進(jìn)程痰洒。

連接建立的超時(shí)

1瓢棒、服務(wù)器主機(jī)沒有處于正常狀態(tài)。
大多數(shù)伯克利系統(tǒng)建立一個(gè)新連接的最長(zhǎng)時(shí)間限制為75秒丘喻。

最大報(bào)文長(zhǎng)度MSS

MSS 表示TCP傳往另一端的最大塊數(shù)據(jù)的長(zhǎng)度脯宿。
當(dāng)一個(gè)連接建立時(shí),連接的雙方都要通告各自的MSS泉粉。
我們已經(jīng)見過(guò)的MSS都是1024连霉,這導(dǎo)致IP數(shù)據(jù)報(bào)通常是40字節(jié)長(zhǎng):20字節(jié)的TCP首部和20字節(jié)的IP首部
MSS并不是任何條件下都可協(xié)商,當(dāng)建立一個(gè)連接時(shí)嗡靡,每一方都有用于通告它期望接收的MSS選項(xiàng)(MSS選項(xiàng)只能出現(xiàn)在SYN報(bào)文段中)跺撼。如果一方不接收來(lái)自另一方的MSS值,則MSS就定為默認(rèn)值536字節(jié)(這個(gè)默認(rèn)值允許20字節(jié)IP首部和20字節(jié)的TCP首部以適合576字節(jié)IP數(shù)據(jù)報(bào))叽躯。

image.png

如果目的IP地址為“非本地的(nonlocal)”(不是一個(gè)網(wǎng)段的)MSS通常的默認(rèn)值為536财边。
大多數(shù)TCP實(shí)現(xiàn)版都提供了一個(gè)配置選項(xiàng),讓系統(tǒng)管理員說(shuō)明不同的子網(wǎng)是屬于本地還是非本地点骑。這個(gè)選項(xiàng)的設(shè)置將確定MSS可以選擇盡可能的大(達(dá)到外出接口的MTU長(zhǎng)度)或是默認(rèn)值536酣难。
MSS讓主機(jī)限制另一端發(fā)送數(shù)據(jù)報(bào)的長(zhǎng)度,加上主機(jī)也能控制它發(fā)送數(shù)據(jù)報(bào)的長(zhǎng)度黑滴,這將使較小MTU連接到一個(gè)網(wǎng)絡(luò)上的主機(jī)避免分段憨募。

TCP的半關(guān)閉

TCP提供了連接的一端在結(jié)束它的發(fā)送后還能接受來(lái)自另一端數(shù)據(jù)的能力,這就是所謂的TCP 的半關(guān)閉袁辈。
為了使用這個(gè)特性菜谣,編程接口必須為應(yīng)用程序提供一種方式來(lái)說(shuō)明“我已經(jīng)完成了數(shù)據(jù)傳送,因此發(fā)送一個(gè)文件結(jié)束(FIN)給另一端晚缩,但我還想接收另一端發(fā)來(lái)的數(shù)據(jù)尾膊,直到它給我發(fā)來(lái)文件結(jié)束(FIN)”

image.png

TCP的狀態(tài)變遷圖

image.png
image.png

兩個(gè)導(dǎo)致進(jìn)入ESTABLISHED狀態(tài)的變遷對(duì)應(yīng)打開一個(gè)連接,而兩個(gè)導(dǎo)致從ESTABLISHED狀態(tài)離開的變遷對(duì)應(yīng)關(guān)閉一個(gè)連接荞彼。
ESTABLISHED狀態(tài)是連接雙方能夠進(jìn)行雙向數(shù)據(jù)傳遞的狀態(tài)冈敛。


image.png

image.png

2MSL等待狀態(tài)

TIME_WAIT狀態(tài)也稱為2MSL等待狀態(tài)。每個(gè)具體TCP實(shí)現(xiàn)必須選擇一個(gè)報(bào)文段最大生存時(shí)間MSL(Maximum Segment Lifetime)鸣皂。它是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長(zhǎng)時(shí)間抓谴。
這個(gè)時(shí)間是有限的暮蹂,因?yàn)門CP報(bào)文段以IP數(shù)據(jù)報(bào)在網(wǎng)絡(luò)內(nèi)傳輸,而IP數(shù)據(jù)報(bào)則有限制其生存時(shí)間的TTL字段癌压。
RFC 793指出MSL為2分鐘仰泻,實(shí)現(xiàn)中的常用值是30秒,1分鐘滩届,或2分鐘集侯。
對(duì)于一個(gè)具體實(shí)現(xiàn)所給定的MSL值,處理的原則是:當(dāng)TCP執(zhí)行一個(gè)主動(dòng)關(guān)閉丐吓,并發(fā)回最后一個(gè)ACK浅悉,該連接必須在TIME_WAIT狀態(tài)停留的時(shí)間為2倍的MSL。這樣可讓TCP再次發(fā)送最后的ACK以防這個(gè)ACK丟失(另一端超時(shí)并重發(fā)最后的FIN)
這種2MSL等待的另一個(gè)結(jié)果是這個(gè)TCP連接在2MSL等待期間券犁,定義這個(gè)連接的插口(客戶的IP地址和端口號(hào)术健,服務(wù)器的IP地址和端口號(hào))不能再被使用。這個(gè)連接只能在2MSL結(jié)束后才能再被使用粘衬。
目前大多數(shù)TCP實(shí)現(xiàn)(如伯克利版)強(qiáng)加了更加嚴(yán)格的限制荞估,在2MSL等待期間,插口中使用的本地端口在默認(rèn)情況下不能再被使用稚新。
在連接處于2MSL等待時(shí)勘伺,任何遲到的報(bào)文段將被丟棄,因?yàn)樘幱?MSL等待的褂删、由該插口對(duì)(socket pair)定義的連接在這段時(shí)間內(nèi)不能被再用飞醉,因此當(dāng)要建立一個(gè)有效的連接時(shí),來(lái)自該連接的一個(gè)較早替身(incarnation)的遲到報(bào)文段作為新連接的一部分不可能不被曲解(一個(gè)連接由一個(gè)插口對(duì)來(lái)定義屯阀,一個(gè)連接的新的實(shí)例(instance)稱為該連接的替身)缅帘。
服務(wù)器通常執(zhí)行被動(dòng)關(guān)閉,不會(huì)進(jìn)入TIME_WAIT狀態(tài)难衰,這暗示如果我們終止一個(gè)客戶程序钦无,并立即重新啟動(dòng)這個(gè)客戶程序,則這個(gè)新客戶程序?qū)⒉荒苤赜孟嗤谋镜囟丝诟窍?duì)客戶雖然沒什么失暂,但是對(duì)于服務(wù)器來(lái)說(shuō),如果我們終止一個(gè)已經(jīng)建立連接的服務(wù)器程序鳄虱,并試圖立即重新啟動(dòng)這個(gè)服務(wù)器程序弟塞,服務(wù)器程序?qū)⒉荒馨阉倪@個(gè)熟知端口賦值給它的端點(diǎn),因?yàn)槟莻€(gè)端口是處于2MSL連接的一部分拙已。在重新啟動(dòng)服務(wù)器程序前宣肚,它需要在1 ~ 4分鐘。

TCP在重啟動(dòng)后的MSL秒內(nèi)不能建立任何連接悠栓,這就稱為平靜時(shí)間(quiet time)

FIN_WAIT_2狀態(tài)
image.png

復(fù)位報(bào)文段

TCP首部中RST比特是用于“復(fù)位”的霉涨。
無(wú)論何時(shí)一個(gè)報(bào)文段發(fā)往基準(zhǔn)的連接(referenced connection)出現(xiàn)錯(cuò)誤,TCP都會(huì)發(fā)出一個(gè)復(fù)位報(bào)文段(基準(zhǔn)連接指目的IP地址和目的端口號(hào)以及源IP和源端口號(hào)指明的連接)惭适。

到不存在的端口的連接請(qǐng)求

產(chǎn)生復(fù)位的一種情況是當(dāng)連接請(qǐng)求到達(dá)時(shí)笙瑟,目的端口沒有進(jìn)程正在聽,對(duì)于UDP的話癞志,會(huì)產(chǎn)生一個(gè)ICMP端口不可達(dá)的消息往枷,而TCP則使用復(fù)位。

異常終止一個(gè)連接

終止一個(gè)連接的正常方式是一方發(fā)送FIN凄杯,有時(shí)這也稱為有序釋放(orderly release)错洁,因?yàn)樵谒信抨?duì)數(shù)據(jù)都已發(fā)送之后才發(fā)送FIN,正常情況下沒有任何數(shù)據(jù)丟失戒突,但也有可能發(fā)送一個(gè)復(fù)位報(bào)文段而不是FIN來(lái)中途釋放一個(gè)連接屯碴。有時(shí)稱這為異常釋放(abortive release)

異常終止一個(gè)連接對(duì)應(yīng)用程序來(lái)說(shuō)有兩個(gè)優(yōu)點(diǎn):
1、丟棄任何待發(fā)數(shù)據(jù)并立即發(fā)送復(fù)位報(bào)文段
2膊存、RST的接收方會(huì)區(qū)分另一端執(zhí)行的是異常關(guān)閉還是正常關(guān)閉导而。應(yīng)用程序使用的API必須提供產(chǎn)生異常關(guān)閉而不是正常關(guān)閉的手段。

檢測(cè)半打開鏈接

如果一方已經(jīng)關(guān)閉或異常終止連接而另一方卻還不知道隔崎,我們將這樣的TCP連接成為半打開(Half-Open)的
只要不打算在半打開連接上傳輸數(shù)據(jù)今艺,扔處于連接狀態(tài)的一方就不會(huì)檢測(cè)另一方已經(jīng)出現(xiàn)異常。
1爵卒、任何一端的主機(jī)異常都可能導(dǎo)致發(fā)生這種情況
2虚缎、當(dāng)客戶主機(jī)突然掉電而不是正常的結(jié)束客戶應(yīng)用程序后再關(guān)機(jī)(可能發(fā)生在使用PC機(jī)作Telnet的客戶主機(jī)上)

同時(shí)打開
image.png

TCP對(duì)于同時(shí)打開,它僅建立一條連接而不是兩條連接
同時(shí)打開情況的狀態(tài)變遷圖:


image.png

兩端幾乎在同時(shí)發(fā)送SYN钓株,并進(jìn)入SYN_SENT狀態(tài)实牡,當(dāng)每一端收到SYN時(shí),狀態(tài)變?yōu)镾YN_RCVD享幽,同時(shí)它們都再發(fā)SYN并對(duì)收到的SYN進(jìn)行確認(rèn)铲掐,當(dāng)雙方都收到SYN及相應(yīng)的ACK時(shí),狀態(tài)都變遷為ESTABLISHED值桩。

一個(gè)同時(shí)打開的連接需要交換4個(gè)報(bào)文段摆霉,比正常的三次握手多一個(gè)。
相對(duì)應(yīng)的也有同時(shí)關(guān)閉奔坟。

image.png

TCP選項(xiàng)

image.png
image.png

TCP服務(wù)器

當(dāng)一個(gè)服務(wù)器進(jìn)程接受一來(lái)自客戶進(jìn)程的服務(wù)請(qǐng)求時(shí)是如何處理端口的携栋?如果多個(gè)連接請(qǐng)求幾乎同時(shí)到達(dá)會(huì)發(fā)生什么情況?
比如咳秉,我們看一個(gè)Telnet婉支,首先處于LISTEN狀態(tài),等待連接請(qǐng)求的到達(dá)澜建,之后主機(jī)啟動(dòng)一個(gè)Telnet客戶程序來(lái)連接這個(gè)Telnet服務(wù)器向挖,會(huì)發(fā)現(xiàn)狀態(tài)變成了ESTABLISHED狀態(tài)蝌以,但是處于LISTEN狀態(tài)的服務(wù)器進(jìn)程仍然存在,這個(gè)服務(wù)器進(jìn)程是當(dāng)前Telnet服務(wù)器用于接收其他的連接請(qǐng)求何之,當(dāng)傳入的連接請(qǐng)求到達(dá)并被接收時(shí)跟畅,系統(tǒng)內(nèi)核中的TCP模塊就創(chuàng)建一個(gè)處于ESTABLISHED狀態(tài)的進(jìn)程,另外處于ESTABLISHED狀態(tài)的連接的端口不會(huì)變化也是23溶推,與處與LISTEN狀態(tài)的進(jìn)程相同徊件。
我們?cè)偃ブ鳈C(jī)啟動(dòng)另一個(gè)Telnet客戶進(jìn)程,并仍與這個(gè)Telnet服務(wù)器進(jìn)行連接蒜危,那么現(xiàn)在有兩條從相同主機(jī)到相同服務(wù)器的處于ESTABLISHED的連接虱痕,它們的本地端口號(hào)均為23,由于它們的遠(yuǎn)端端口號(hào)不同辐赞,這不會(huì)造成沖突部翘,因?yàn)槊總€(gè)Telnet客戶進(jìn)程要是用一個(gè)外設(shè)端口,并且這個(gè)外設(shè)端口會(huì)選擇為主機(jī)當(dāng)前未曾使用的端口占拍,因此它們的端口號(hào)肯定不同略就。

呼入連接請(qǐng)求隊(duì)列

一個(gè)并發(fā)服務(wù)器調(diào)用一個(gè)新的進(jìn)程來(lái)處理每個(gè)客戶請(qǐng)求,因此處于被動(dòng)連接請(qǐng)求的服務(wù)器應(yīng)該始終準(zhǔn)備處理下一個(gè)呼入的連接請(qǐng)求晃酒,這正是使用并發(fā)服務(wù)器的根本原因表牢,但仍有可能出現(xiàn)當(dāng)服務(wù)器在創(chuàng)建一個(gè)新的進(jìn)程時(shí),或操作系統(tǒng)正忙于處理優(yōu)先級(jí)更高的進(jìn)程時(shí)贝次,到達(dá)多個(gè)連接請(qǐng)求崔兴,當(dāng)服務(wù)器正處于忙時(shí),TCP是如何處理這些呼入的連接請(qǐng)求蛔翅?

image.png
image.png
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末敲茄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子山析,更是在濱河造成了極大的恐慌堰燎,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笋轨,死亡現(xiàn)場(chǎng)離奇詭異秆剪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)爵政,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門仅讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人钾挟,你說(shuō)我怎么就攤上這事洁灵。” “怎么了掺出?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵徽千,是天一觀的道長(zhǎng)苫费。 經(jīng)常有香客問(wèn)我,道長(zhǎng)罐栈,這世上最難降的妖魔是什么黍衙? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮荠诬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘位仁。我一直安慰自己柑贞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布聂抢。 她就那樣靜靜地躺著钧嘶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪琳疏。 梳的紋絲不亂的頭發(fā)上有决,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音空盼,去河邊找鬼书幕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛揽趾,可吹牛的內(nèi)容都是我干的台汇。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼篱瞎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼苟呐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起俐筋,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤牵素,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后澄者,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笆呆,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年闷哆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腰奋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抱怔,死狀恐怖劣坊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屈留,我是刑警寧澤局冰,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布测蘑,位于F島的核電站,受9級(jí)特大地震影響康二,放射性物質(zhì)發(fā)生泄漏碳胳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一沫勿、第九天 我趴在偏房一處隱蔽的房頂上張望挨约。 院中可真熱鬧,春花似錦产雹、人聲如沸诫惭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夕土。三九已至,卻和暖如春瘟判,著一層夾襖步出監(jiān)牢的瞬間怨绣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工拷获, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篮撑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓刀诬,卻偏偏與公主長(zhǎng)得像咽扇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子陕壹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

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