【转】运输层TCP协议详细介绍
【轉(zhuǎn)】運(yùn)輸層TCP協(xié)議詳細(xì)介紹
TCP是TCP/IP協(xié)議族中非常復(fù)雜的一個(gè)協(xié)議。它具有以下特點(diǎn):
????1:面向連接的運(yùn)輸層協(xié)議。在使用TCP協(xié)議之前,首先需要建立TCP連接。傳送數(shù)據(jù)完畢后,必須釋放已經(jīng)建立的TCP連接。
????2:一條TCP連接有兩個(gè)端點(diǎn),連接是點(diǎn)對(duì)點(diǎn)的。
????3:提供可靠交付的服務(wù)。通過(guò)TCP連接傳送的數(shù)據(jù),不會(huì)出現(xiàn)差錯(cuò)不會(huì)丟失并且按序到達(dá)。
????4:提供全雙工通信。TCP允許通信雙方的應(yīng)用程序進(jìn)程在任何時(shí)候都能發(fā)送數(shù)據(jù)。TCP連接的兩端都設(shè)有緩存,分為發(fā)送緩存和接收緩存,用來(lái)臨時(shí)存放雙向通信的數(shù)據(jù)。發(fā)送時(shí),應(yīng)用程序把數(shù)據(jù)傳給TCP的緩存后,就可以做自己的事情了。TCP會(huì)在合適的時(shí)候把數(shù)據(jù)發(fā)送出去。接收時(shí),TCP把接收到的數(shù)據(jù)放入緩存,供上層的應(yīng)用程序讀取。
????5:面向字節(jié)流。雖然應(yīng)用程序和TCP的交互是一次一個(gè)數(shù)據(jù)塊,但TCP把應(yīng)用程序交下來(lái)的數(shù)據(jù)看成一串無(wú)結(jié)構(gòu)的字節(jié)流。TCP對(duì)應(yīng)用進(jìn)程一次把多長(zhǎng)的報(bào)文發(fā)送到TCP緩存中是不關(guān)心的。TCP根據(jù)對(duì)方給出的窗口值和當(dāng)前網(wǎng)絡(luò)的擁塞程度決定一個(gè)報(bào)文段包含多少字節(jié)。如果應(yīng)用程序傳到TCP緩存的數(shù)據(jù)塊太長(zhǎng),TCP就會(huì)把它劃分短些再傳送。如果應(yīng)用程序發(fā)來(lái)的數(shù)據(jù)太少時(shí),TCP將會(huì)等待積累足夠多的字節(jié)后再構(gòu)成報(bào)文段發(fā)送出去。
?
?? ?? TCP連接的端點(diǎn)叫做套接字。它是由IP和端口號(hào)構(gòu)成。每一條TCP連接唯一的被通信兩端的兩個(gè)端點(diǎn)所確定。同一個(gè)IP地址可以有多個(gè)不同的TCP連接,而同一個(gè)端口號(hào)也可以出現(xiàn)在多個(gè)不同的TCP連接中。
???? TCP發(fā)送的報(bào)文段是交付給IP層傳送的,但I(xiàn)P層只提供盡最大努力的交付。也就是說(shuō)TCP下面的網(wǎng)絡(luò)所提供的是不可靠的服務(wù)。可靠傳輸必須依靠TCP來(lái)實(shí)現(xiàn)。停止等待協(xié)議就是一種方式。
?
?? ? 停止等待就是每發(fā)送完一個(gè)分組就停止發(fā)送,等待接收方的確認(rèn),在收到確認(rèn)后再傳送下一個(gè)分組。如果發(fā)送方在一段時(shí)間后仍然沒(méi)有收到確認(rèn),就認(rèn)為剛才發(fā)送的分組丟失了,因而重傳前面發(fā)送過(guò)的分組,這被稱為超時(shí)重傳。要實(shí)現(xiàn)超時(shí)重傳,就要在每發(fā)送完一個(gè)分組后設(shè)置一個(gè)超時(shí)計(jì)時(shí)器。如果在超時(shí)計(jì)時(shí)器到期之前收到了對(duì)方的確認(rèn),就撤銷已設(shè)置的超時(shí)計(jì)時(shí)器。因此發(fā)送方在發(fā)送完一個(gè)分組之后,必須暫時(shí)保存已發(fā)送的分組的副本。只有在收到響應(yīng)的確認(rèn)后才能清除暫時(shí)保留的分組的副本。分組和確認(rèn)分組都必須進(jìn)行編號(hào),這樣才能知道哪一個(gè)發(fā)送過(guò)的數(shù)據(jù)已被確認(rèn),那些沒(méi)有收到確認(rèn)。超時(shí)計(jì)時(shí)器設(shè)置的重傳時(shí)間應(yīng)該比數(shù)據(jù)在分組傳輸?shù)钠骄禃r(shí)間更長(zhǎng)一些。超時(shí)重傳時(shí)間的設(shè)定是非常復(fù)雜的,因?yàn)橐寻l(fā)送的分組到底經(jīng)過(guò)那些網(wǎng)絡(luò),以及這些網(wǎng)絡(luò)會(huì)產(chǎn)生多大的延遲都是不確定的。
?
??????? 如果發(fā)送方發(fā)送了數(shù)據(jù)后,在超時(shí)時(shí)間內(nèi)沒(méi)有收到接收方的確認(rèn),它會(huì)重傳數(shù)據(jù)。如果此時(shí)接受方再次接收到了此數(shù)據(jù),它會(huì)將此數(shù)據(jù)丟棄,并向發(fā)送方發(fā)送確認(rèn)。發(fā)送方?jīng)]有收到確認(rèn),可能是因?yàn)榻邮芊降拇_認(rèn)出錯(cuò)或丟失。發(fā)送方還可能收到重復(fù)的確認(rèn),對(duì)待重復(fù)的確認(rèn)只需要丟棄即可。上述可靠的傳輸協(xié)議被稱為自動(dòng)重傳請(qǐng)求ARQ(Automatic?Repeat?Request)。采用停止等待協(xié)議可能會(huì)導(dǎo)致信道利用率非常低,為了提高傳輸效率,需要使用流水線傳輸。也就是說(shuō)發(fā)送方可以連續(xù)發(fā)送多個(gè)分組,不必沒(méi)發(fā)完一個(gè)分組就停下來(lái)等待對(duì)方的確認(rèn)。這樣可以使信道上一直有數(shù)據(jù)不間斷的在傳送。這被稱為連續(xù)ARQ協(xié)議或滑動(dòng)窗口協(xié)議。它比較復(fù)雜但卻是TCP協(xié)議的精髓。
?
?????? 所謂滑動(dòng)窗口就是說(shuō)位于此窗口內(nèi)的分組可以被連續(xù)的發(fā)送出去,而不需要等待對(duì)方的確認(rèn)。發(fā)送方每收到一個(gè)確認(rèn),就會(huì)把發(fā)送窗口向前滑動(dòng)一個(gè)分組的位置。假設(shè)此時(shí)1-5個(gè)分組位于發(fā)送窗口內(nèi),這5個(gè)分組就會(huì)被連續(xù)的發(fā)送出去。當(dāng)發(fā)送方收到第一個(gè)分組的確認(rèn)后,就會(huì)向后移動(dòng)一個(gè)分組的位置,此時(shí)就可以發(fā)送第六個(gè)分組了。接收方一般都采用累積確認(rèn)的方式。也就是說(shuō),接收方不必對(duì)收到的每個(gè)分組逐個(gè)發(fā)送確認(rèn),而是可以收到幾個(gè)分組后,對(duì)按序到達(dá)的最后一個(gè)分組發(fā)送確認(rèn)。這樣就表示到這個(gè)分組為止的所有分組都被正確接收。如果此時(shí)發(fā)送方發(fā)送了前5個(gè)分組,而第三個(gè)分組丟失了,這是接收方只能對(duì)前兩個(gè)分組發(fā)送確認(rèn)。發(fā)送方不知道后面三個(gè)分組的下落。實(shí)際上僅僅第三個(gè)分組沒(méi)有收到,但是發(fā)送方仍然會(huì)發(fā)送后三個(gè)分組。
?
?? ? TCP是面向字節(jié)流的,但是TCP傳送的數(shù)據(jù)卻是報(bào)文段。一個(gè)TCP報(bào)文段分為首部和數(shù)據(jù)兩部分。只有真正弄清TCP的首部各字段的作用才能掌握TCP的原理。
?? ? TCP的前20個(gè)字節(jié)是固定的。后面的40字節(jié)是根據(jù)需要增加的。因此TCP首部的最小長(zhǎng)度時(shí)20。
???? 1:源端口和目的端口:各占兩個(gè)字節(jié)。
???? 2:序號(hào):四個(gè)字節(jié)。共2的32次方個(gè)序號(hào)。TCP連接中傳送的字節(jié)流中的每一個(gè)字節(jié)都按順序編號(hào)。此處的序號(hào)字段指的是本報(bào)文段所發(fā)送的數(shù)據(jù)第一個(gè)字節(jié)的序號(hào)。
???? 3:確認(rèn)號(hào):4個(gè)字節(jié)。表示期望收到對(duì)方下一個(gè)報(bào)文段的第一個(gè)數(shù)據(jù)字節(jié)的序號(hào)。如確認(rèn)號(hào)是N,則表明序號(hào)N-1之前的數(shù)據(jù)都正確收到。確認(rèn)號(hào)也是4個(gè)字節(jié),可以對(duì)4GB數(shù)據(jù)進(jìn)行編號(hào)。
?? ? 4:數(shù)據(jù)偏移,4位。它指出TCP報(bào)文段的數(shù)據(jù)起始處距離TCP報(bào)文段起始處有多遠(yuǎn)。這個(gè)字段實(shí)際上指出了TCP的首部。由于首部中有長(zhǎng)度不確定的選項(xiàng)字段,因此此數(shù)據(jù)偏移是必要的。數(shù)據(jù)偏移只有4位,但是它的一個(gè)單位代表4字節(jié)。因此數(shù)據(jù)偏移的最大值是60(15*4)。即TCP首部的最大長(zhǎng)度。
???? 5:保留?6位。保留為以后使用。都是0.
???? 6:緊急URG?當(dāng)此處為1時(shí),表明緊急指針字段有效。它告訴系統(tǒng)此報(bào)文段有緊急數(shù)據(jù),需要盡快傳送。系統(tǒng)會(huì)把緊急數(shù)據(jù)插入TCP緩存的最前面。它和緊急指針字段配合使用。
???? 7:確認(rèn)ACK:當(dāng)ACK=1時(shí),確認(rèn)號(hào)字段才有效。當(dāng)ACK=0時(shí)確認(rèn)號(hào)無(wú)效。當(dāng)連接建立前ACK=0,建立之后ACK就一直是1了。
???? 8:推送PSH。當(dāng)PSH=1時(shí),系統(tǒng)會(huì)立即將此報(bào)文段發(fā)送出去,而不再等待整個(gè)緩存都被填滿后才向上交付。
???? 9:復(fù)位RST。當(dāng)其為1,時(shí),表明TCP出現(xiàn)嚴(yán)重錯(cuò)誤,必須釋放連接然后再重新建立連。
???? 10:同步SYN:在連接建立時(shí)用來(lái)同步序號(hào)。當(dāng)其為1而ACK=0時(shí),表明這是一個(gè)(同步)連接請(qǐng)求報(bào)文段。當(dāng)對(duì)方同意后,應(yīng)在響應(yīng)報(bào)文段中使用SYN=1,ACK=1。因此SYN=1,要么表示連接請(qǐng)求要么表示連接接受報(bào)文。
?? ? 11:終止FIN:用來(lái)釋放連接。當(dāng)其為1時(shí),表明此報(bào)文段的發(fā)送方的數(shù)據(jù)已經(jīng)發(fā)送完畢,要求釋放連接。
?? ? 12:窗口:2字節(jié)。窗口指發(fā)送方的接收窗口。它告訴對(duì)方:從本報(bào)文段首部中的確認(rèn)號(hào)算起,接收方目前允許對(duì)方發(fā)送的數(shù)據(jù)量。之所以有此限制是因?yàn)榻邮辗降臄?shù)據(jù)緩存空間是有限的。它指出現(xiàn)在允許對(duì)方發(fā)送數(shù)據(jù)量。由于接收緩存不斷變化,因此窗口值也不斷變化。
???? 13:檢驗(yàn)和:2字節(jié)。檢驗(yàn)和檢驗(yàn)?的是首部和數(shù)據(jù)這兩部分。在計(jì)算時(shí)還應(yīng)加上12字節(jié)的偽首部。
???? 14:緊急指針:2字節(jié),此字段只在緊急URG=1時(shí)才有意義。它指出本報(bào)文段中緊急數(shù)據(jù)的字節(jié)數(shù)。由于緊急數(shù)據(jù)放在了緩沖區(qū)最前方,緊急指針指出的是緊急數(shù)據(jù)的末尾在報(bào)文段的位置。當(dāng)所有的緊急數(shù)據(jù)都處理完后,TCP?就告訴應(yīng)用程序恢復(fù)正常操作。
???? 15:選項(xiàng):長(zhǎng)度可變,最長(zhǎng)可達(dá)40字節(jié)。當(dāng)沒(méi)有選項(xiàng)時(shí),首部長(zhǎng)度時(shí)20.
?
?? ? MSS是選項(xiàng)的一種。它被稱為最大報(bào)文段長(zhǎng)度,是每個(gè)TCP報(bào)文段中數(shù)據(jù)字段的最大長(zhǎng)度。它加上TCP首部才是整個(gè)TCP報(bào)文段。再加上20字節(jié)的IP首部才能組裝成一個(gè)IP數(shù)據(jù)報(bào)。當(dāng)MSS非常小時(shí),網(wǎng)絡(luò)的利用率就低。如果發(fā)送只含一個(gè)字節(jié)的數(shù)據(jù)時(shí),在IP層傳輸至少需要40字節(jié)的開銷(IP頭20字節(jié),TCP頭至少20)。到鏈路層還需要開銷。如果MSS非常大,在IP層傳輸時(shí)就可能要分片,到終點(diǎn)后再將各個(gè)分片組裝成原來(lái)的TCP報(bào)文段,這也會(huì)使開銷增大。因此,MSS可以盡量大,只要在IP層傳輸時(shí)不分片就行了。MSS的默認(rèn)長(zhǎng)度時(shí)536。
????窗口擴(kuò)大選項(xiàng)是為了擴(kuò)大窗口,窗口字段長(zhǎng)度是16位,因此最大的窗口大小是64字節(jié)。窗口擴(kuò)大選項(xiàng)占3個(gè)字節(jié)。每一個(gè)字節(jié)表示移位值。新的窗口值等于原來(lái)的16+窗口擴(kuò)大選項(xiàng)的值。這相當(dāng)于把窗口值向左移動(dòng)移位值位。
????時(shí)間戳選項(xiàng)占10字節(jié),最主要的兩個(gè)地段是:時(shí)間戳值和時(shí)間戳回送回答字段。
時(shí)間戳選項(xiàng)具有以下兩個(gè)功能
????1:計(jì)算往返時(shí)間。
????2:用于處理TCP序號(hào)超過(guò)2的32次方的情況。這又被稱為防止序號(hào)繞回。在報(bào)文段中加入時(shí)間戳就可以區(qū)分新的報(bào)文段和遲到很久的報(bào)文段。
?
????socket的兩端分別有兩個(gè)窗口,發(fā)送窗口和接收窗口。滑動(dòng)窗口的單位是字節(jié),假設(shè)A收到了B的確認(rèn)報(bào)文段,其中窗口時(shí)20,而確認(rèn)號(hào)是31,這表明B期望接受的下一個(gè)序號(hào)是31,到序號(hào)30為止的數(shù)據(jù)已經(jīng)收到了。根據(jù)這兩個(gè)數(shù)據(jù),A就構(gòu)造自己的發(fā)送窗口。它的起始值為31,而末尾值為50。發(fā)送窗口表示在沒(méi)有收到B的確認(rèn)前,A可以連續(xù)把窗口內(nèi)的數(shù)據(jù)都發(fā)送出去。
?
???? 凡是已經(jīng)發(fā)送過(guò)得數(shù)據(jù),在未收到確認(rèn)之前都必須暫時(shí)保留,以便在在超時(shí)重傳。發(fā)送窗口內(nèi)的序號(hào)表示允許發(fā)送的序號(hào)。
?? ? 發(fā)送窗口與緩存的關(guān)系。
???? 發(fā)送窗口存儲(chǔ)應(yīng)用程序?qū)⒁l(fā)送的數(shù)據(jù),以及發(fā)送但卻為收到確認(rèn)的數(shù)據(jù)。?發(fā)送窗口只是發(fā)送緩存的一部分,已經(jīng)被確認(rèn)過(guò)的數(shù)據(jù)應(yīng)當(dāng)從發(fā)送緩存中刪除。因此發(fā)送緩存和發(fā)送窗口的后沿是重合的。
接收緩存用來(lái)暫時(shí)存放按需到達(dá)的,但還未被應(yīng)用程序讀取的數(shù)據(jù)以及未按序到達(dá)的數(shù)據(jù)。?如果收到的分組有差錯(cuò),就要丟棄。如果接收應(yīng)用程序來(lái)不及讀取,接收緩存就會(huì)被填滿,就會(huì)減少接受窗口,直到減為0。反之就可以增大。
???? 雖然發(fā)送方的發(fā)送窗口是根據(jù)接收方方接收窗口設(shè)置但是,但同一時(shí)刻,發(fā)送窗口并不一定與接收窗口相同。這是因?yàn)橥ㄟ^(guò)網(wǎng)絡(luò)傳送窗口值需要經(jīng)歷一定的延遲。
?? ? TCP要求接收方必須有累計(jì)確認(rèn)的功能,這樣可以減小傳輸開銷。接收方可以在合適的時(shí)候發(fā)送確認(rèn),也可以在自己有數(shù)據(jù)發(fā)送時(shí)把確認(rèn)信息捎上。但應(yīng)該注意的是接收方不應(yīng)過(guò)分推遲發(fā)送確認(rèn),否則會(huì)導(dǎo)致發(fā)送方不必要的重傳,這反而會(huì)浪費(fèi)網(wǎng)絡(luò)資源。
?????TCP利用滑動(dòng)窗口來(lái)實(shí)現(xiàn)流量控制。所謂流量控制就是讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來(lái)得及接受。在連接建立時(shí),發(fā)送方告訴接收方我的接受窗口是x,接收方收到后會(huì)設(shè)置自己的發(fā)送窗口。發(fā)送方的發(fā)送窗口不能超過(guò)接收方給出的接收窗口的數(shù)值。TCP窗口的單位是字節(jié),而不是報(bào)文段。在每次發(fā)送數(shù)據(jù)是報(bào)文段內(nèi)會(huì)將此時(shí)接受窗口告訴發(fā)送者。發(fā)送者會(huì)根據(jù)收到的報(bào)文段接收窗口的值調(diào)整自己的發(fā)送窗口。當(dāng)接收方接收緩存滿時(shí)就發(fā)送給發(fā)送方零窗口,告訴發(fā)送方停止發(fā)送。假設(shè)過(guò)一段時(shí)間接收方調(diào)整接收窗口為100,而此報(bào)文段在傳送過(guò)程中丟失,這就導(dǎo)致發(fā)送方等待接收方的非零窗口通知,而接收方在等待發(fā)送方的數(shù)據(jù)。這樣就導(dǎo)致了死鎖。為了防止這種情況,TCP為每個(gè)連接設(shè)置一個(gè)持續(xù)計(jì)時(shí)器。TCP連接的一方收到零窗口通知后,就啟動(dòng)計(jì)時(shí)器,設(shè)置的時(shí)間到期后它會(huì)發(fā)送一個(gè)探測(cè)報(bào)文段。如果此時(shí)返回的仍然是零窗口,則重新設(shè)定計(jì)時(shí)器。如果窗口不是零,那么死鎖的僵局就可以被打破了。
?
????? TCP是面向連接的協(xié)議。分為三個(gè)階段:
????? 一:連接建立
????? 二:數(shù)據(jù)傳送
????? 三:連接釋放。
?
????在TCP連接建立的過(guò)程中需要解決一下三個(gè)問(wèn)題:
????1:要使每一方能夠通知對(duì)方的存在。
????2:允許雙方協(xié)商一些參數(shù)。如窗口最大值、是否使用窗口擴(kuò)大選項(xiàng)和時(shí)間戳選項(xiàng)。
??? 3:能夠?qū)\(yùn)輸實(shí)體資源,如緩存進(jìn)行分配。
?
??? TCP連接的建立采取客戶服務(wù)器方式。主動(dòng)發(fā)起連接的叫做客戶。被動(dòng)等待連接建立的應(yīng)用程序叫做服務(wù)器。
?
????TCP的建立連接需要客戶服務(wù)器通信三次。這就是常說(shuō)的三次握手。
????首先服務(wù)器創(chuàng)建socket,綁定端口并進(jìn)入監(jiān)聽模式等待客戶端的請(qǐng)求。客戶端B向服務(wù)器發(fā)送連接請(qǐng)求報(bào)文段。此時(shí)同部位SYN=1,初始序號(hào)seq=x,ACK=0(連接未建立,確認(rèn)字段無(wú)效)。此時(shí)客戶端進(jìn)入同步--已發(fā)送狀態(tài)。
????服務(wù)器收到連接請(qǐng)求,如同意建立連接,則會(huì)發(fā)送確認(rèn)。此時(shí)SYN=1,ACK=1,確認(rèn)號(hào)ack=x+1。設(shè)置自己的初始序號(hào)seq=y。此時(shí)服務(wù)器進(jìn)入同步--收到狀態(tài)。
????客戶端收到確認(rèn)后,還要給服務(wù)器進(jìn)行確認(rèn),此時(shí)ACK=1,ack=y+1.seq=x+1。此時(shí)的報(bào)文段已經(jīng)可以攜帶數(shù)據(jù)了。此時(shí)客戶端進(jìn)入已經(jīng)建立狀態(tài)。
????服務(wù)器收到后也進(jìn)入已建立狀態(tài)。
?
????? 很多人會(huì)很疑問(wèn)會(huì)什么客戶端還需要發(fā)送一次確認(rèn),這主要是防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到服務(wù)器。比如客戶端發(fā)出連接請(qǐng)求,但此請(qǐng)求丟失,沒(méi)有收到服務(wù)器發(fā)來(lái)的額確認(rèn)。于是一段時(shí)間后客戶端繼續(xù)請(qǐng)求,此請(qǐng)求被服務(wù)器接收,客戶端收到了服務(wù)器的請(qǐng)求。數(shù)據(jù)傳輸完畢后,連接被釋放。如果此時(shí)客戶端第一次發(fā)送的報(bào)文段在網(wǎng)絡(luò)中滯留一段時(shí)間后到達(dá)服務(wù)器,服務(wù)器收到這個(gè)失效的請(qǐng)求,卻誤以為是客戶端發(fā)出的新的連接請(qǐng)求。于是向客戶端發(fā)送同一連接請(qǐng)求。由于客戶端沒(méi)有發(fā)出連接請(qǐng)求,當(dāng)然會(huì)將此報(bào)文丟棄。而服務(wù)器卻一直等待客戶端的回復(fù)。
????? TCP連接的釋放。
????? 數(shù)據(jù)傳輸結(jié)束后任何一方都可以申請(qǐng)釋放連接。A向B發(fā)送連接釋放報(bào)文段,并停止發(fā)送數(shù)據(jù)。主動(dòng)關(guān)閉TCP連接。此時(shí)?A的連接釋放報(bào)文段首部FIN應(yīng)置為1,序號(hào)seq=x,等于前面已傳送過(guò)得數(shù)據(jù)的最后一個(gè)序號(hào)加一。此時(shí)A進(jìn)入終止--等待(FIN-WAIT-1)狀態(tài)1。等待B的確認(rèn)。TCP規(guī)定FIN報(bào)文段即使不攜帶數(shù)據(jù)也要消耗一個(gè)序號(hào)。
B收到連接釋放報(bào)文段后即發(fā)出確認(rèn),確認(rèn)號(hào)ack是x+1。seq=y。然后B就進(jìn)入了關(guān)閉--等待(CLOSE_WAIT)狀態(tài)。此時(shí)?從A到B這個(gè)方向的連接已經(jīng)釋放了,這是TCP處于半關(guān)閉狀態(tài)。即A不會(huì)在發(fā)送數(shù)據(jù),但B要發(fā)送數(shù)據(jù)A?仍要接收。A收到B的確認(rèn)后就進(jìn)入了終止--等待(FIN-WAIT-2)狀態(tài)2,等待B發(fā)出的連接釋放報(bào)文段。若B沒(méi)有?數(shù)據(jù)要發(fā)送給A,它發(fā)出連接釋放報(bào)文段將FIN置為1,ACK=1,seq=w,ack=u+1.此時(shí)B處于最后確認(rèn)狀態(tài)。?等待A的確認(rèn)。A在收到B的連接釋放報(bào)文段后,必須對(duì)此進(jìn)行確認(rèn)。將ACK置為1,確認(rèn)號(hào)ack=w+1,?seq=u+1。然后進(jìn)入時(shí)間--等待(TIME-WAIT)狀態(tài),此時(shí)TCP連接還沒(méi)有被釋放,還必須經(jīng)過(guò)時(shí)間計(jì)時(shí)器設(shè)置的2MSL后?A才進(jìn)入關(guān)閉狀態(tài)。MSL為Maximum?segment?Lifetime。即最長(zhǎng)報(bào)文段壽命。
?
?????? 之所以要設(shè)置這個(gè)最大報(bào)文段壽命,有兩個(gè)原因:
?????? 1:為保證A發(fā)送的最后一個(gè)ACK報(bào)文能夠到達(dá)B。因?yàn)樗锌赡軄G失,此時(shí)便導(dǎo)致B收不到對(duì)方對(duì)FIN+ACK報(bào)文段的確認(rèn)。此后B會(huì)超時(shí)重傳。由于A設(shè)置了2MSL計(jì)時(shí)器,使得A有機(jī)會(huì)收到B的報(bào)文。如果A不設(shè)置2MSL,而是發(fā)送完ACK報(bào)文段后立即釋放,就無(wú)法收到B重傳的FIN+ACK報(bào)文段。B也就無(wú)法按正常步驟進(jìn)入CLOSED狀態(tài)。
?????? 2:防止已失效的連接請(qǐng)求報(bào)文段出現(xiàn)。A發(fā)送完最后一個(gè)ACK報(bào)文段后,等待2MSL就可使本此連接所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失,不會(huì)對(duì)下一次的連接造成影響。
?????? 除等待計(jì)時(shí)器外,TCP還設(shè)置一個(gè)保活計(jì)時(shí)器。如果客戶端主動(dòng)與服務(wù)器建立起連接,而此后客戶端突然出現(xiàn)故障,此后服務(wù)器不能收到從客戶端發(fā)來(lái)的數(shù)據(jù),此時(shí)應(yīng)采取一定的措施,是服務(wù)器不白白等待。服務(wù)器每收到一次客戶端的數(shù)據(jù)就重置保活計(jì)時(shí)器,時(shí)間通常是2小時(shí)。若兩小時(shí)沒(méi)有收到客戶端的數(shù)據(jù),服務(wù)器就發(fā)送探測(cè)報(bào)文,以后每隔75分鐘發(fā)送一次,若一連發(fā)送10探測(cè)報(bào)文段后仍無(wú)客戶端的響應(yīng),服務(wù)器就認(rèn)為客戶端出現(xiàn)故障,接著就關(guān)閉了連接。
?????? 在客戶--服務(wù)器模型中,通常務(wù)器分配的一個(gè)socket對(duì)某一端口進(jìn)行監(jiān)聽。一旦監(jiān)聽到有連接請(qǐng)求。就調(diào)用accept,accept將會(huì)產(chǎn)生新的socket。然后服務(wù)器創(chuàng)建新的線程,新的socket將會(huì)作為新線程的參數(shù)。系統(tǒng)會(huì)為這個(gè)新的socket分配一個(gè)服務(wù)器端的自由端口號(hào),這個(gè)套接字專用于在連接建立后與客戶端交換數(shù)據(jù)。它一般被稱為響應(yīng)套接字。
? 看一個(gè)例子:
?
?
posted on 2018-07-17 23:14 時(shí)空觀察者9號(hào) 閱讀(...) 評(píng)論(...) 編輯 收藏
總結(jié)
以上是生活随笔為你收集整理的【转】运输层TCP协议详细介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转】计算机中浮点数的表示
- 下一篇: 【转】c++虚函数实现原理