傳輸層-TCP, TCP頭部結(jié)構(gòu) ,TCP序列號(hào)和確認(rèn)號(hào)詳解
TCP主要解決下面的三個(gè)問(wèn)題
1.數(shù)據(jù)的可靠傳輸。發(fā)送方如何知道發(fā)出的數(shù)據(jù),接收方已經(jīng)收到。
現(xiàn)實(shí)生活中,我們?cè)诖螂娫挼臅r(shí)候,當(dāng)我們自己根對(duì)方說(shuō)了一句話或者一段話之后,我們都會(huì)等待對(duì)方的回應(yīng),譬如她們會(huì)回答"哦"、"嗯"、"知道了",這時(shí)我們就會(huì)知道對(duì)方已經(jīng)聽(tīng)到我們自己剛才說(shuō)的話,如果她們不給予回應(yīng)則會(huì)以為她們沒(méi)有在聽(tīng)我講話,也就是沒(méi)有收到我發(fā)送的消息。
TCP可靠傳輸?shù)膶?shí)現(xiàn)正是基于這樣的例子,對(duì)于發(fā)送方發(fā)送的數(shù)據(jù),接收方在接受到數(shù)據(jù)之后必須要給予確認(rèn),確認(rèn)它收到了數(shù)據(jù)。如果在規(guī)定時(shí)間內(nèi),沒(méi)有給予確認(rèn)則意味著接收方?jīng)]有接受到數(shù)據(jù),然后發(fā)送方對(duì)數(shù)據(jù)進(jìn)行重發(fā)。
重發(fā): 當(dāng)用戶交給TCP傳輸?shù)臄?shù)據(jù)量很大時(shí),如果使用簡(jiǎn)單的重發(fā)機(jī)制,即重發(fā)所有的數(shù)據(jù),勢(shì)必會(huì)嚴(yán)重占用和浪費(fèi)帶寬資源,甚至造成網(wǎng)絡(luò)擁塞。因此TCP會(huì)將用戶需要傳輸?shù)臄?shù)據(jù)進(jìn)行分組,即將數(shù)據(jù)進(jìn)行切割,分成多個(gè)數(shù)據(jù)段(data segment),并給每個(gè)數(shù)據(jù)段編號(hào)。
TCP報(bào)文段首部中通過(guò)長(zhǎng)度為32bit的字段來(lái)表示這個(gè)TCP報(bào)文段的序號(hào),另外通過(guò)長(zhǎng)度為32bit的字段來(lái)表示確認(rèn)報(bào)文段要確認(rèn)的報(bào)文段的序號(hào)。
2.接收方的流量控制。因?yàn)楦鞣N原因,接收方可能來(lái)不及處理發(fā)送方發(fā)送的數(shù)據(jù),而造成沒(méi)有及時(shí)回應(yīng)發(fā)送方,造成發(fā)送方不斷的重發(fā)數(shù)據(jù),最后造成接收方的主機(jī)宕機(jī)。
現(xiàn)實(shí)生活中,我們?nèi)ヒ恍衢T(mén)的景點(diǎn)或者游樂(lè)園的某個(gè)娛樂(lè)項(xiàng)目時(shí),都會(huì)需要進(jìn)行排隊(duì),如果是小長(zhǎng)假,則會(huì)出現(xiàn)人山人海的場(chǎng)景,這是這些機(jī)構(gòu)就會(huì)控制每一次參觀該景點(diǎn)的人數(shù)。網(wǎng)絡(luò)應(yīng)用程序也是如此,當(dāng)數(shù)據(jù)到達(dá)主機(jī)之后,TCP會(huì)將該數(shù)據(jù)放入相應(yīng)的隊(duì)列(又稱為緩沖區(qū))(如果讓你自己基于UDP實(shí)現(xiàn)一個(gè)TCP模塊供自己的應(yīng)用程序使用,你也會(huì)采用這種方式),等待監(jiān)聽(tīng)該端口的應(yīng)用程序從隊(duì)列中獲取數(shù)據(jù),應(yīng)用程序一次所能處理的數(shù)據(jù)有限,因此不可能一次性取出隊(duì)列中的所有數(shù)據(jù),當(dāng)隊(duì)列已經(jīng)滿了,則無(wú)法再存放新的數(shù)據(jù),只能將接受到的數(shù)據(jù)丟棄,因此TCP協(xié)議需要提供流量控制的能力,控制發(fā)送方每次發(fā)送數(shù)據(jù)的大小。
3.計(jì)算機(jī)網(wǎng)絡(luò)的擁塞控制。數(shù)據(jù)在計(jì)算機(jī)網(wǎng)絡(luò)之上傳輸,當(dāng)出現(xiàn)數(shù)據(jù)擁塞時(shí)如何進(jìn)行處理
現(xiàn)實(shí)生活中,高速公路也會(huì)堵車,在一段高速公路上,每輛車都在以很快的速度在運(yùn)行,彼此并沒(méi)有慢下來(lái),但是為什么還是會(huì)出現(xiàn)堵車呢?通常都是因?yàn)槊慷蔚缆返某休d能力不一樣,譬如當(dāng)一段8車道公路上的汽車行駛到4車道公路上時(shí),在這兩段道路交匯的地方就會(huì)出現(xiàn)堵車。
計(jì)算機(jī)網(wǎng)絡(luò)是由無(wú)數(shù)的數(shù)據(jù)鏈路組成的,每一段鏈路的承載能力不一樣,也會(huì)出現(xiàn)數(shù)據(jù)擁堵的情況,這通常是由路由器和交換機(jī)的處理能力不同造成的。我們還需要知道,這種情況下的擁塞是不能避免的,因?yàn)槲覀儫o(wú)法要求所有鏈路的承載能力一樣,因此我們只能對(duì)擁塞進(jìn)行控制。TCP協(xié)議對(duì)擁塞控制也提出了響應(yīng)的解決方案,這也是為什么TCP叫做傳輸控制協(xié)議而不叫做可靠傳輸協(xié)議的原因吧,同時(shí)也解釋了為什么在計(jì)算機(jī)網(wǎng)絡(luò)可靠性能大大提供的今天,TCP還繼續(xù)發(fā)揮著其作用的原因。
TCP連接管理
我們都說(shuō)TCP是面向連接的,UDP不是面向連接的。那么什么是連接呢?為什么TCP需要面向連接呢?
連接是一個(gè)動(dòng)作?,F(xiàn)實(shí)生活中,我們想和一個(gè)通話,我們需要先撥打她的電話,等待她接聽(tīng)我們的打電話之后就可以進(jìn)行通話了,當(dāng)我們通話結(jié)束之后還需要掛斷電話。
電話的連接會(huì)接通通信雙方之間的電路,是一條真實(shí)存在的電路,在拆除這條電路之前,第三方是不能和兩者之中的任何一方建立通信電路。和電話不同,TCP連接產(chǎn)生的通道是虛擬的,任何第三方端口都可以和兩者之中的任何一個(gè)端口建立通道。我們稱建立虛擬通道的過(guò)程為連接的建立。
連接是可靠傳輸?shù)那疤?,而不是可靠傳輸?shù)谋WC。在QQ這些聊天軟件支持離線消息之前,人們?cè)诎l(fā)送消息之前總要確保對(duì)方在線,因?yàn)槿绻麑?duì)方不在線,消息根本就不會(huì)被對(duì)方收到,也就不存在對(duì)你發(fā)送的消息進(jìn)行回應(yīng)。TCP通過(guò)在連接這個(gè)動(dòng)作讓接收方知道發(fā)送方想要發(fā)送數(shù)據(jù)給它,如果接收方允許,則連接建立,這時(shí)雙方之間便可以進(jìn)行數(shù)據(jù)傳輸,接收到數(shù)據(jù)之后須確認(rèn)數(shù)據(jù)收到。如果不建立連接,則無(wú)法實(shí)現(xiàn)可靠傳輸,因?yàn)閷?duì)于發(fā)送方發(fā)送的數(shù)據(jù),可能接收方的主機(jī)根本就沒(méi)有在監(jiān)聽(tīng)該端口。例如,在采用UDP的P2P實(shí)現(xiàn)中中仍然需要信令服務(wù)器,為什么需要信令服務(wù)器呢?因?yàn)閷?duì)方可能根本就沒(méi)有啟動(dòng)該P(yáng)2P程序或者其它原因無(wú)法跟你進(jìn)行通訊。簡(jiǎn)而言之,連接的作用就是讓通訊雙方知道并準(zhǔn)備好通訊。
連接的建立-三次握手
TCP的可靠傳輸是通過(guò)確認(rèn)和重傳來(lái)實(shí)現(xiàn)的,因此
連接的建立過(guò)程
TCP連接的建立采用的是C/S(Client/Server,客戶端/服務(wù)器)模型。由客戶端發(fā)出建立連接的請(qǐng)求。
下面我們使用'ACK=1'這種方式來(lái)表示控制位中的相應(yīng)位是否置1,'ACK=0'或者不說(shuō)明則都為0。并使用'ack=1'這種方式表示TCP數(shù)據(jù)段首部中的確認(rèn)序號(hào),使用'seq=1'來(lái)表示TCP數(shù)據(jù)段首部中的發(fā)送序號(hào)。
Client首先向Server發(fā)出建立連接的TCP報(bào)文段(SYN=1,seq=x(表示隨機(jī)產(chǎn)生一個(gè)值,我們假設(shè)為100)),并等待Server的確認(rèn)(確認(rèn)收到該建立連接的請(qǐng)求)
Server收到該建立連接的請(qǐng)求之后,如果同意建立連接,則發(fā)送TCP報(bào)文段(SYN=1,seq=y(也是隨機(jī)產(chǎn)生一個(gè)值,我們假設(shè)為21),ACK=1,ack=x+1(這里表示發(fā)送方的x號(hào)數(shù)據(jù)段已經(jīng)收到,這里為101))給Client表示確認(rèn)接收到該TCP報(bào)文,并等待Client確認(rèn)該TCP報(bào)文已經(jīng)收到
Client收到Server的確認(rèn)報(bào)文段之后,再次向Server發(fā)送TCP報(bào)文段(seq=x+1(這里為101),ACK=1,ack=y+1(這里為22)),確認(rèn)Server的確認(rèn)報(bào)文已經(jīng)收到。
我們可以看到,控制字段中的SYN是用來(lái)建立一個(gè)TCP連接的,只在前兩次"握手"中置為1,第三次"握手"置為0."我想和你談話(SYN),我愿意和你談話(SYN,ACK),那我們開(kāi)始吧(ACK)".
連接的斷開(kāi)
通過(guò)TCP三次握手建立的通信屬于全雙工通信,因此每個(gè)方向都必須單獨(dú)地進(jìn)行關(guān)閉。關(guān)閉的原則就是當(dāng)其中一方A完成數(shù)據(jù)的傳輸并且不再傳輸數(shù)據(jù)時(shí),發(fā)送一個(gè)控制位FIN=1的TCP數(shù)據(jù)段來(lái)告知另一方B"我的數(shù)據(jù)已經(jīng)傳輸完畢,并且不再傳輸數(shù)據(jù)",另一方B收到數(shù)據(jù)之后依舊發(fā)送確認(rèn)TCP數(shù)據(jù)段,來(lái)表示A=>B方向的一條連接已經(jīng)斷開(kāi),此時(shí)TCP連接處于半關(guān)閉狀態(tài)。需要注意的是,這里的不再傳輸數(shù)據(jù)是指A不再傳輸用戶數(shù)據(jù),對(duì)于B傳輸?shù)臄?shù)據(jù),A仍然要接收并給予確認(rèn)。
當(dāng)B發(fā)送完數(shù)據(jù)之后并準(zhǔn)備斷開(kāi)連接時(shí),發(fā)送一個(gè)控制位FIN=1,ACK=1(ack=A的FIN報(bào)文段的序號(hào))的TCP報(bào)文段,并等待A的確認(rèn),A收到B的FIN報(bào)文段后給予確認(rèn),至此整個(gè)TCP連接關(guān)閉。
為了防止因?yàn)閿?shù)據(jù)傳輸延時(shí)造成B的FIN報(bào)文段比B的有效數(shù)據(jù)傳輸報(bào)文段(用戶數(shù)據(jù))提前到達(dá),因A會(huì)等待2MSL之后才真正關(guān)閉TCP連接。
TCP的有限狀態(tài)機(jī)
TCP連接建立:
- 首先,服務(wù)器監(jiān)聽(tīng)一個(gè)TCP端口,此時(shí)該端口處于Listen狀態(tài)。
- 一段時(shí)間后,客戶端發(fā)送一個(gè)TCP連接請(qǐng)求,客戶端的端口就出處于SYN_SENT狀態(tài),當(dāng)服務(wù)器接收到一個(gè)客戶端的TCP連接請(qǐng)求時(shí),即收到客戶端的SYN報(bào)文段,服務(wù)器監(jiān)聽(tīng)的端口就會(huì)切換到SYN_RCVD狀態(tài),服務(wù)器向客戶端發(fā)送SYN+ACK報(bào)文段==>問(wèn)題0
- 當(dāng)客戶端收到服務(wù)器發(fā)送的SYN+ACK報(bào)文段時(shí),客戶端的端口切換到ESTAB-LISTEN狀態(tài),客戶端同時(shí)向服務(wù)器發(fā)送SYN報(bào)文段確認(rèn) ==>問(wèn)題1
- 當(dāng)服務(wù)器收到客戶端的ACK報(bào)文段時(shí),服務(wù)器的端口切換到ESTAB-LISTEN狀態(tài)。
問(wèn)題0:當(dāng)客戶端發(fā)送的SYN報(bào)文段,沒(méi)有得到服務(wù)器的任何響應(yīng)怎么辦獲者收到服務(wù)器的REST響應(yīng)當(dāng)客戶端發(fā)送一個(gè)SYN報(bào)文段之后就會(huì)啟動(dòng)定時(shí)器,如果在規(guī)定的時(shí)間內(nèi)沒(méi)有收到服務(wù)器的任何響應(yīng)或者收到服務(wù)器的RESR響應(yīng),則會(huì)重新發(fā)送SYN報(bào)文段。如果在幾次重發(fā)后仍然沒(méi)有得到服務(wù)器的SYN+ACK響應(yīng)就會(huì)放棄,端口切換CLOSE狀態(tài),并報(bào)告上層。
問(wèn)題1:如果當(dāng)客戶端發(fā)送給服務(wù)器的SYN報(bào)文段丟失了會(huì)怎樣?
連接仍然能正常工作。因?yàn)榭蛻舳艘呀?jīng)處于ESTABLISHED狀態(tài),所以客戶端能夠像服務(wù)器發(fā)送數(shù)據(jù)。由于每個(gè)TCP報(bào)文段中都有ACK標(biāo)識(shí)位,而在確認(rèn)序號(hào)字段中包含正確的數(shù)值。所以當(dāng)客戶端發(fā)送的第一個(gè)數(shù)據(jù)到達(dá)服務(wù)器時(shí),服務(wù)器的端口就會(huì)切換到ESTABLISHED狀態(tài)。這實(shí)際上是TCP的重點(diǎn),即每個(gè)TCP報(bào)文段報(bào)告發(fā)送方希望看到的下一個(gè)序號(hào),即使這個(gè)序號(hào)與以前的一個(gè)或多個(gè)報(bào)文段包含的序號(hào)重復(fù)。**
TCP的可靠傳輸
TCP的可靠傳輸是通過(guò)確認(rèn)和超時(shí)重傳的機(jī)制來(lái)實(shí)現(xiàn)的,而確認(rèn)和超時(shí)重傳的具體的實(shí)現(xiàn)是通過(guò)以字節(jié)為單位的滑動(dòng)窗口機(jī)制來(lái)完成。
滑動(dòng)窗口機(jī)制
雖然上層應(yīng)用和TCP的交互是一次一個(gè)數(shù)據(jù)快(大小不等),但是TCP把上層應(yīng)用程序交付下來(lái)的數(shù)據(jù)看成僅僅是一串連續(xù)的無(wú)結(jié)構(gòu)字節(jié)流。
發(fā)送窗口:在未收到對(duì)方的ACK確認(rèn)的情況下,只有發(fā)送窗口內(nèi)的數(shù)據(jù)才能連續(xù)地發(fā)送出去。凡事已經(jīng)發(fā)送過(guò)的數(shù)據(jù),在未收到ACK確認(rèn)之間都必須暫時(shí)保留在發(fā)送窗口內(nèi),以便超時(shí)重傳使用。
-
接收窗口:緩沖區(qū),用來(lái)接收發(fā)送方的TCP數(shù)據(jù)段。
停止-等待協(xié)議
發(fā)送方和接收方都采用窗口大小為1的滑動(dòng)窗口,即發(fā)送窗口和接受窗口都為1個(gè)最大TCP數(shù)據(jù)段的大小。
停止等待協(xié)議的規(guī)則是:
- 發(fā)送方發(fā)完1個(gè)分組并收到接收方ACK確認(rèn)之后才能發(fā)送下一個(gè)分組;
- 如果接收方收到一個(gè)錯(cuò)誤的分組,則給發(fā)送方發(fā)送一個(gè)否認(rèn)分組NAK,發(fā)送方收到NAK分組后重發(fā),并繼續(xù)等待發(fā)送方的ACK確認(rèn)
- 如果發(fā)送方在規(guī)定的時(shí)限內(nèi)(發(fā)送完一個(gè)分組,就開(kāi)啟一個(gè)定時(shí)器)沒(méi)有收到接收方的ACK確認(rèn)分組,則重新發(fā)送該分組。
后退N協(xié)議
后退N協(xié)議的思想是流水線傳輸,即可以連續(xù)發(fā)送多個(gè)分組,而不必每發(fā)完一個(gè)分組就等待接收方的ACK確認(rèn)。
規(guī)則如下:
- 發(fā)送窗口的大小為n,接收窗口的大小為1
- 發(fā)送方在發(fā)送完一個(gè)數(shù)據(jù)分組之后,不是停下來(lái)等待接收方的ACK確認(rèn),而是可以連續(xù)再發(fā)送若干個(gè)分組。
- 接收方在收到發(fā)送方發(fā)送的分組之后發(fā)送ACK確認(rèn)分組,并移動(dòng)接收窗口。
- 如果發(fā)送方發(fā)送一共連續(xù)發(fā)送了4個(gè)分組,中間的第2個(gè)分組丟失,則接收方要求發(fā)送方重傳后面的3個(gè)分組(第2個(gè)、第3個(gè)、第4個(gè)分組)。(因?yàn)榈?個(gè)和第4個(gè)分組不接序)這也說(shuō)明了該協(xié)議為什么叫做后退N協(xié)議。
描述:
雖然在收到了有差錯(cuò)的2號(hào)分組之后,收到了正確的3號(hào)分組和4號(hào)分組,但是由于接收端只按順序接收數(shù)據(jù)分組,造成3號(hào)和4號(hào)分組不能和1號(hào)分組接序而被丟棄,等到A的定時(shí)器超時(shí)重發(fā)。
選擇重傳
選擇重傳協(xié)議是對(duì)后退N協(xié)議的一種優(yōu)化,其只是選擇性重發(fā)那些確實(shí)丟失的分組。
規(guī)則:
- 發(fā)送窗口的大小為m,接收窗口的大小為n
- 接收方先接收序號(hào)不連續(xù)的分組,并發(fā)送ACK確認(rèn),然后等待發(fā)送方重發(fā)丟失的分組(發(fā)送方每收到一個(gè)ACK確認(rèn)就會(huì)關(guān)閉相應(yīng)的定時(shí)器,最終沒(méi)有收到ACK確認(rèn)的分組的定時(shí)器超時(shí),發(fā)送方會(huì)再次重發(fā))
- 收到重發(fā)的分組后給予ACK確認(rèn),再對(duì)全部分組進(jìn)行排序,最后交給上層應(yīng)用。
通知窗口
TCP采用通知窗口實(shí)現(xiàn)對(duì)發(fā)送端的流量控制,通知窗口大小的單位是字節(jié)。TCP通過(guò)在TCP數(shù)據(jù)段首部的窗口字段中填入當(dāng)前設(shè)定的接收窗口(即通知窗口)的大小,用來(lái)告知對(duì)方'我方當(dāng)前的接收窗口大小',以實(shí)現(xiàn)流量控制。
通信雙方的發(fā)送窗口大小由雙方在連接建立是商定,在通信過(guò)程,雙方可以動(dòng)態(tài)地根據(jù)自己的情況調(diào)整對(duì)方的發(fā)送窗口大小。
TCP擁塞控制
在某段時(shí)間,如果對(duì)計(jì)算機(jī)網(wǎng)絡(luò)中某些資源的需求超過(guò)了所能提供該資源的總和,網(wǎng)絡(luò)的性能就要變壞——產(chǎn)生擁塞(congestion)。即當(dāng)需要>供給時(shí)會(huì)造成網(wǎng)絡(luò)擁塞。如果計(jì)算機(jī)網(wǎng)絡(luò)中有許多資源同時(shí)產(chǎn)生擁塞,網(wǎng)絡(luò)的性能就要明顯變壞,整個(gè)網(wǎng)絡(luò)的吞吐量將隨輸入負(fù)荷的增大而下降。
TCP協(xié)議通過(guò)慢啟動(dòng)機(jī)制、擁塞避免機(jī)制、加速遞減機(jī)制、快重傳和快恢復(fù)機(jī)制來(lái)共同實(shí)現(xiàn)擁塞控制。
在擁塞控制中還有一個(gè)"擁塞窗口"的概念,該窗口由發(fā)送方根據(jù)當(dāng)前計(jì)算機(jī)網(wǎng)絡(luò)的擁塞情況來(lái)計(jì)算,和通知窗口共通作用于發(fā)送窗口,"擁塞窗口"的單位也是字節(jié),通常擁塞窗口的初始值為一個(gè)最大TCP報(bào)文段的大小是,但下面我們以每個(gè)傳輸輪次所能發(fā)送TCP數(shù)據(jù)段(用戶數(shù)據(jù))的次數(shù)作為其單位來(lái)描述。
TCP的慢啟動(dòng)機(jī)制、擁塞避免機(jī)制和加速遞減機(jī)制都是通過(guò)改變擁塞窗口的大小來(lái)時(shí)對(duì)發(fā)送方的發(fā)送窗口進(jìn)行控制。
擁塞控制與流量控制的關(guān)系
擁塞控制是一個(gè)全局性的控制,涉及到計(jì)算機(jī)網(wǎng)絡(luò)中所有的主機(jī)、路由器以及降低網(wǎng)絡(luò)傳輸性能的相關(guān)因素。而流量控制只涉及到通信雙方之間的收發(fā)平衡。
TCP在控制數(shù)據(jù)傳輸時(shí),既要考慮接收端的接收能力,又要避免網(wǎng)絡(luò)擁塞,因而發(fā)送方的發(fā)送窗口大小為通知窗口和擁塞窗口的最小值。
傳輸輪次
在TCP的擁塞避免中,我們規(guī)定:每發(fā)送擁塞窗口值個(gè)數(shù)的TCP數(shù)據(jù)段(有效數(shù)據(jù)承載),并且全部收到發(fā)送方對(duì)這些數(shù)據(jù)的ACK確認(rèn),我們就稱完成了1個(gè)傳輸輪次。
例如,擁塞窗口=4,當(dāng)發(fā)送方發(fā)送了4個(gè)TCP報(bào)文段,并收到這4個(gè)TCP報(bào)文段的ACK確認(rèn),我們就稱完成了一個(gè)傳輸輪次。
慢啟動(dòng)機(jī)制
慢啟動(dòng)通過(guò)逐步增大擁塞窗口的值來(lái)控制網(wǎng)絡(luò)擁塞。
慢啟動(dòng)機(jī)制規(guī)定:
- 擁塞窗口的初始值為1
- 每收到一個(gè)對(duì)發(fā)出的數(shù)據(jù)段的ACK確認(rèn),便將擁塞窗口的值增加1倍
我們可以發(fā)現(xiàn),每完成一次傳輸輪次,擁塞窗口的值就翻倍,即擁塞窗口隨著傳輸輪次的增加成指數(shù)增長(zhǎng)。
隨著傳輸輪次的增加,擁塞窗口的值會(huì)變得很大,因此TCP擁塞控制給慢啟動(dòng)增加一個(gè)閾值(又稱慢啟動(dòng)門(mén)限),當(dāng)擁塞窗口>閾值時(shí),就要進(jìn)行嘗試擁塞避免。
當(dāng) 擁塞窗口 < 閾值 時(shí),使用慢啟動(dòng)算法
當(dāng) 擁塞窗口 > 閾值 時(shí),使用擁塞避免算法
當(dāng) 擁塞窗口 = 閾值時(shí),既可以使用慢啟動(dòng)算法,也可時(shí)使用擁塞避免算法。
隨著網(wǎng)絡(luò)擁塞的出現(xiàn)和變化,閾值也會(huì)不斷變化。TCP擁塞控制中,閾值的初始值為16
擁塞避免
擁塞避免算法的思路是讓擁塞窗口緩慢地增大,呈線性增長(zhǎng),即每完成一個(gè)傳輸輪次,擁塞窗口增加1。
擁塞避免是指在擁塞避免階段把擁塞窗口控制為按線性規(guī)律增長(zhǎng),使網(wǎng)絡(luò)比較不容易出現(xiàn)擁塞,而不是完全能夠避免擁塞。
加速遞減機(jī)制
如果在使用慢啟動(dòng)機(jī)制或者擁塞避免機(jī)制中,發(fā)送數(shù)據(jù)時(shí),出現(xiàn)了定時(shí)器超時(shí),便執(zhí)行加速遞減機(jī)制:
- 立刻將慢啟動(dòng)門(mén)限置為當(dāng)前擁塞窗口大小的一般,然后擁塞窗口的值重置為1
- 執(zhí)行使用慢啟動(dòng)機(jī)制
快重傳和快恢復(fù)
如果發(fā)送方設(shè)置定時(shí)器超時(shí),那么很可能是網(wǎng)絡(luò)出現(xiàn)了擁塞,致使TCP報(bào)文段在網(wǎng)絡(luò)中的某處被丟棄。在這種情況下,TCP馬上把擁塞窗口減少到1,并執(zhí)行慢開(kāi)始算法,同時(shí)慢開(kāi)始門(mén)限值減半。這是不采用快重傳機(jī)制的情況:
快重傳機(jī)制要求接收方每收到一個(gè)失序的TCP報(bào)文段后就立即發(fā)出重復(fù)確認(rèn)(為了使發(fā)送方及早知道沒(méi)有到達(dá)對(duì)方)而不要等待自己發(fā)送數(shù)據(jù)時(shí)才進(jìn)行確認(rèn)。
快重傳算法規(guī)定:發(fā)送方只要連續(xù)收到3個(gè)重復(fù)確認(rèn)就應(yīng)當(dāng)立即重傳未被確認(rèn)的報(bào)文段。
快恢復(fù)
當(dāng)發(fā)送端收到連續(xù)三個(gè)重復(fù)的確認(rèn)時(shí),就執(zhí)行“乘法減小”算法,把慢開(kāi)始門(mén)限 ssthresh 減半。但接下去不執(zhí)行慢開(kāi)始算法。
由于發(fā)送方現(xiàn)在認(rèn)為網(wǎng)絡(luò)很可能沒(méi)有發(fā)生擁塞,因此現(xiàn)在不執(zhí)行慢開(kāi)始算法,即擁塞窗口 cwnd 現(xiàn)在不設(shè)置為 1,而是設(shè)置為慢開(kāi)始門(mén)限 ssthresh 減半后的數(shù)值,然后開(kāi)始執(zhí)行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。
TCP習(xí)題
A,B兩臺(tái)機(jī)器都正常工作,B機(jī)器未監(jiān)聽(tīng)任何端口.如果A機(jī)器向B機(jī)器80端口發(fā)送SYN包,會(huì)收到何種類型的回包?
RST包
TCP建立連接的過(guò)程采用三次握手,已知第三次握手報(bào)文的發(fā)送序列號(hào)為1000,確認(rèn)序列號(hào)為2000,請(qǐng)問(wèn)第二次握手報(bào)文的發(fā)送序列號(hào)和確認(rèn)序列號(hào)分別為?
1999,1000
某一速率為100M的交換機(jī)有20個(gè)端口,其一個(gè)端口上連著一臺(tái)筆記本電腦,此電腦從迅雷上下載一部1G的電影需要的時(shí)間可能是多久?
交換機(jī)為獨(dú)占帶寬,即每個(gè)端口數(shù)據(jù)通過(guò)率為為最大100Mb/s。注意單位是Mb。因此最短時(shí)間為:
1GB/(100Mb/s)=1024MB/(12.5MB/s)=81.92s。
這里涉及到單位換算問(wèn)題
消息傳遞部分為三個(gè)功能級(jí)?
第一級(jí)為數(shù)據(jù)鏈路功能級(jí),第二級(jí)是信令鏈路功能級(jí),第三級(jí)是信令網(wǎng)功能級(jí)
最后對(duì)tcp頭結(jié)構(gòu)做一些補(bǔ)充說(shuō)明
TCP頭部結(jié)構(gòu)
TCP頭部信息出現(xiàn)在每個(gè)TCP報(bào)文段中,用于指定通信的源端端口,目的端端口,管理TCP連接等,本節(jié)詳細(xì)介紹TCP的頭部結(jié)構(gòu),包括固定頭部結(jié)構(gòu)和頭部選項(xiàng)。
TCP固定頭部結(jié)構(gòu)
TCP頭部結(jié)構(gòu)如圖3-3所示,其中的諸多字段為管理TCP連接和控制數(shù)據(jù)流提供了足夠的信息。
16位端口號(hào)(port number):告知主機(jī)該報(bào)文段是來(lái)自哪里(源端口)以及傳給哪個(gè)上層協(xié)議或應(yīng)用程序(目的端口)的。進(jìn)行TCP通信時(shí),客戶端通常使用系統(tǒng)自動(dòng)選擇的臨時(shí)端口號(hào),而服務(wù)器則使用知名服務(wù)端口號(hào)。1.3節(jié)中提到過(guò),所有知名服務(wù)使用的端口號(hào)都定義在/etc/services文件中。
32位序號(hào)(sequence number):一次TCP通信(從TCP連接建立到斷開(kāi))過(guò)程中某一個(gè)傳輸方向上的字節(jié)流的每個(gè)字節(jié)的編號(hào)。假設(shè)主機(jī)A和主機(jī)B進(jìn)行TCP通信,A發(fā)送給B的第一個(gè)TCP報(bào)文段中,序號(hào)值被系統(tǒng)初始化為某個(gè)隨機(jī)值ISN(Initial Sequence Number,初始序號(hào)值)。那么在該傳輸方向上(從A到B),后續(xù)的TCP報(bào)文段中序號(hào)值將被系統(tǒng)設(shè)置成ISN加上該報(bào)文段所攜帶數(shù)據(jù)的第一個(gè)字節(jié)在整個(gè)字節(jié)流中的偏移。例如,某個(gè)TCP報(bào)文段傳送的數(shù)據(jù)是字節(jié)流中的第1025~2048字節(jié),那么該報(bào)文段的序號(hào)值就是ISN+1025。另外一個(gè)傳輸方向(從B到A)的TCP報(bào)文段的序號(hào)值也具有相同的含義。
32位確認(rèn)號(hào)(acknowledgement number):用作對(duì)另一方發(fā)送來(lái)的TCP報(bào)文段的響應(yīng)。其值是收到的TCP報(bào)文段的序號(hào)值加1。假設(shè)主機(jī)A和主機(jī)B進(jìn)行TCP通信,那么A發(fā)送出的TCP報(bào)文段不僅攜帶自己的序號(hào),而且包含對(duì)B發(fā)送來(lái)的TCP報(bào)文段的確認(rèn)號(hào)。反之,B發(fā)送出的TCP報(bào)文段也同時(shí)攜帶自己的序號(hào)和對(duì)A發(fā)送來(lái)的報(bào)文段的確認(rèn)號(hào)。
4位頭部長(zhǎng)度(header length):標(biāo)識(shí)該TCP頭部有多少個(gè)32bit字(4字節(jié))。因?yàn)?位最大能表示15,所以TCP頭部最長(zhǎng)是60字節(jié)。
6位標(biāo)志位包含如下幾項(xiàng):
- URG標(biāo)志,表示緊急指針(urgent pointer)是否有效。
- ACK標(biāo)志,表示確認(rèn)號(hào)是否有效。我們稱攜帶ACK標(biāo)志的TCP報(bào)文段為確認(rèn)報(bào)文段。
- PSH標(biāo)志,提示接收端應(yīng)用程序應(yīng)該立即從TCP接收緩沖區(qū)中讀走數(shù)據(jù),為接收后續(xù)數(shù)據(jù)騰出空間(如果應(yīng)用程序不將接收到的數(shù)據(jù)讀走,它們就會(huì)一直停留在TCP接收緩沖區(qū)中)。
- RST標(biāo)志,表示要求對(duì)方重新建立連接。我們稱攜帶RST標(biāo)志的TCP報(bào)文段為復(fù)位報(bào)文段。
- SYN標(biāo)志,表示請(qǐng)求建立一個(gè)連接。我們稱攜帶SYN標(biāo)志的TCP報(bào)文段為同步報(bào)文段。
- FIN標(biāo)志,表示通知對(duì)方本端要關(guān)閉連接了。我們稱攜帶FIN標(biāo)志的TCP報(bào)文段為結(jié)束報(bào)文段。
16位窗口大?。╳indow size):是TCP流量控制的一個(gè)手段。這里說(shuō)的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告訴對(duì)方本端的TCP接收緩沖區(qū)還能容納多少字節(jié)的數(shù)據(jù),這樣對(duì)方就可以控制發(fā)送數(shù)據(jù)的速度。
16位校驗(yàn)和(TCP checksum):由發(fā)送端填充,接收端對(duì)TCP報(bào)文段執(zhí)行CRC算法以檢驗(yàn)TCP報(bào)文段在傳輸過(guò)程中是否損壞。注意,這個(gè)校驗(yàn)不僅包括TCP頭部,也包括數(shù)據(jù)部分。這也是TCP可靠傳輸?shù)囊粋€(gè)重要保障。
16位緊急指針(urgent pointer):是一個(gè)正的偏移量。它和序號(hào)字段的值相加表示最后一個(gè)緊急數(shù)據(jù)的下一字節(jié)的序號(hào)。因此,確切地說(shuō),這個(gè)字段是緊急指針相對(duì)當(dāng)前序號(hào)的偏移,不妨稱之為緊急偏移。TCP的緊急指針是發(fā)送端向接收端發(fā)送緊急數(shù)據(jù)的方法。我們將在后面討論TCP緊急數(shù)據(jù)。
補(bǔ)充實(shí)際數(shù)據(jù)包分析 結(jié)合上面的理論,下面我們?cè)L問(wèn)網(wǎng)頁(yè)來(lái)捕獲數(shù)據(jù)包,通過(guò)實(shí)際的數(shù)據(jù)包來(lái)驗(yàn)證序列號(hào)和確認(rèn)號(hào)在TCP連接建立、傳輸數(shù)據(jù)以及關(guān)閉連接時(shí)的變化。打開(kāi)科來(lái)網(wǎng)絡(luò)分析系統(tǒng),首先為減少數(shù)據(jù)干擾,在過(guò)濾器中設(shè)置只捕獲TCP協(xié)議的數(shù)據(jù),然后開(kāi)始捕獲,同時(shí),訪問(wèn)www.csna.cn ,待頁(yè)面下載完成后,停止捕獲。此次環(huán)境中,客戶端為192.168.0.92,服務(wù)器為:222.77.187.23。3.1 TCP建立連接 在捕獲的數(shù)據(jù)包中,首先我們來(lái)查看建立連接的三次握手信息,并且觀察數(shù)據(jù)包中序列號(hào)和確認(rèn)號(hào)的變化。為了讓大家看的更加明白,我在這里使用了“添加數(shù)據(jù)包注釋”的功能。我們先來(lái)查看建立連接的第一步,如圖1所示。