TCP:傳輸控制協(xié)議

一、TCP的可靠性

TCP向應(yīng)用層提供與UDP完全不同的服務(wù)。它提供一種面向連接的、可靠的字節(jié)流服務(wù)。
TCP通過(guò)下列方式來(lái)提供可靠性:

  • 應(yīng)用程序被分割成TCP認(rèn)為最適合發(fā)送的數(shù)據(jù)塊,這和UDP完全不同,應(yīng)用程序產(chǎn)生的數(shù)據(jù)報(bào)UDP不做處理。由TCP傳遞給IP的信息單位稱為報(bào)文段
  • 當(dāng)TCP發(fā)出一個(gè)段后,它啟動(dòng)一個(gè)定時(shí)器,等待目的端確認(rèn)收到這個(gè)報(bào)文段。如果不能及時(shí)收到一個(gè)確認(rèn),將重發(fā)這個(gè)報(bào)文段。(超時(shí)重傳
  • 當(dāng)TCP收到發(fā)自TCP連接的另一端數(shù)據(jù)時(shí),它將發(fā)送一個(gè)確認(rèn)。這個(gè)確認(rèn)不是立即發(fā)送,通常將推遲幾分之一秒
  • TCP將保持它首部和數(shù)據(jù)的檢驗(yàn)和
  • 既然TCP報(bào)文段作為IP數(shù)據(jù)報(bào)來(lái)傳輸,而IP數(shù)據(jù)報(bào)的到達(dá)可能會(huì)失序,因此TCP報(bào)文段的到達(dá)也可能會(huì)失序。如果必要,TCP將對(duì)收到的數(shù)據(jù)進(jìn)行重新序,將收到的數(shù)據(jù)以正確的順序交給應(yīng)用層
  • TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機(jī)致使較慢主機(jī)的緩沖區(qū)溢出。

二、TCP的首部

TCP數(shù)據(jù)被封裝在一個(gè)ip數(shù)據(jù)報(bào)中


報(bào)文頭各個(gè)部分說(shuō)明:

  • 源端口號(hào)和目的端口號(hào)
    分別占用16位,表示源端口號(hào)和目的端口號(hào);用于區(qū)別主機(jī)中的不同進(jìn)程, 而IP地址是用來(lái)區(qū)分不同的主機(jī)的,源端口號(hào)和目的端口號(hào)配合上IP首部中的源IP地址和目的IP地址就能唯一 的確定一個(gè)TCP連接
  • 32位序號(hào)(Sequence Number)
    用來(lái)標(biāo)識(shí)從TCP發(fā)端向TCP收端發(fā)送的數(shù)據(jù)字節(jié)流,它表示在這個(gè)報(bào)文段中的的第一個(gè)數(shù)據(jù)字節(jié)在數(shù)據(jù)流中的序號(hào);主要用來(lái)解決網(wǎng)絡(luò)報(bào)亂序的問(wèn)題;
  • 32位確認(rèn)序號(hào)(Acknowledgment Number)
    32位確認(rèn)序列號(hào)包含發(fā)送確認(rèn)的一端所期望收到的下一個(gè)序號(hào),因此,確認(rèn)序號(hào)應(yīng) 當(dāng)是上次已成功收到數(shù)據(jù)字節(jié)序號(hào)加1。不過(guò),只有當(dāng)標(biāo)志位中的ACK標(biāo)志(下面介紹)為1時(shí)該確認(rèn)序列號(hào)的字 段才有效。主要用來(lái)解決不丟包的問(wèn)題;
  • TCP Flags 標(biāo)志位
    TCP首部中有6個(gè)標(biāo)志比特,它們中的多個(gè)可同時(shí)被設(shè)置為1,主要是用于操控TCP的狀態(tài)機(jī)的,依次 為URG,ACK,PSH,RST,SYN,F(xiàn)IN。每個(gè)標(biāo)志位的意思如下:
    1. URG
      當(dāng)URG=1,表明緊急指針字段有效。告訴系統(tǒng)此報(bào)文段中有緊急數(shù)據(jù);
    2. ACK
      僅當(dāng)ACK=1時(shí),確認(rèn)號(hào)字段才有效。TCP規(guī)定,在連接建立后所有報(bào)文的傳輸都必須把ACK置1;
    3. PSH
      這個(gè)標(biāo)志位表示Push操作。所謂Push操作就是指在數(shù)據(jù)包到達(dá)接收端以后,立即傳送給應(yīng)用程序,而不是在緩沖區(qū)中排隊(duì);一端的應(yīng)用進(jìn)程希望在鍵入一個(gè)命令后立即就能收到對(duì)方的響應(yīng)
    4. RST
      當(dāng)RST=1,表明TCP連接中出現(xiàn)嚴(yán)重差錯(cuò),必須釋放連接,然后再重新建立連接;
    5. SYN
      在連接建立時(shí)用來(lái)同步序號(hào)。當(dāng)SYN=1,ACK=0,表明是連接請(qǐng)求報(bào)文,若同意連接,則響應(yīng)報(bào)文中應(yīng)該使SYN=1,ACK=1;
    6. FIN
      表示發(fā)送端已經(jīng)達(dá)到數(shù)據(jù)末尾,也就是說(shuō)雙方的數(shù)據(jù)傳送完成,沒(méi)有數(shù)據(jù)可以傳送了,發(fā)送FIN標(biāo)志 位的TCP數(shù)據(jù)包后,連接將被斷開。這個(gè)標(biāo)志的數(shù)據(jù)包也經(jīng)常被用于進(jìn)行端口掃描。
  • 窗口
    指的是通知接收方,發(fā)送本報(bào)文你需要有多大的空間來(lái)接受;
  • 校驗(yàn)和
    校驗(yàn)首部和數(shù)據(jù)這兩部分;

三、TCP的三次握手和四次揮手

握手和揮手時(shí)均是客戶端率先發(fā)出請(qǐng)求

  • 三次握手
    最開始的時(shí)候客戶端和服務(wù)器均處于關(guān)閉狀態(tài)。主動(dòng)打開的連接為客戶端,被動(dòng)打開的連接為服務(wù)器。
  1. TCP客戶進(jìn)程創(chuàng)建傳輸控制塊TCB(TCP Block),然后向服務(wù)器發(fā)送連接請(qǐng)求報(bào)文。這時(shí)報(bào)文首部中的同部位SYN=1,同時(shí)選擇一個(gè)初始序列號(hào)seq=x,此時(shí)客戶端進(jìn)入SYN-SENT(同步已發(fā)送)狀態(tài)。TCP規(guī)定,SYN(SYN=1時(shí))報(bào)文段不能攜帶數(shù)據(jù),但需要消耗掉一個(gè)序號(hào)
  2. TCP服務(wù)器收到請(qǐng)求報(bào)文后,如果同意連接,則發(fā)出確認(rèn)報(bào)文。確認(rèn)報(bào)文中ACK=1,SYN=1,確認(rèn)號(hào)是ack=x+1,同時(shí)自己也要初始化一個(gè)序列號(hào)seq=y。此時(shí),TCP服務(wù)器進(jìn)程進(jìn)入了SYN-RCVD(同步收到)狀態(tài)。這個(gè)報(bào)文也不能攜帶數(shù)據(jù),但是同樣要消耗一個(gè)序號(hào)。
  3. TCP客戶進(jìn)程收到確認(rèn)后,還要向服務(wù)器給出確認(rèn)。確認(rèn)報(bào)文的ACK=1,ack=y+1,自己的序列號(hào)seq=x+1,此時(shí),TCP連接建立,客戶端進(jìn)入ESTABLISHED(已建立連接)狀態(tài)。TCP規(guī)定,ACK報(bào)文段可以攜帶數(shù)據(jù),但是如果不攜帶數(shù)據(jù)則不消耗序號(hào)。
    雙方分別同步各自的序列號(hào) x y 。最大報(bào)文段長(zhǎng)度在第三次握手時(shí)協(xié)商出

    為什么TCP客戶端最后還要發(fā)送一次確認(rèn)?

一句話,主要防止已經(jīng)失效的連接請(qǐng)求報(bào)文突然又傳送到了服務(wù)器,從而產(chǎn)生錯(cuò)誤。
如果使用的是兩次握手建立連接,假設(shè)有這樣一種場(chǎng)景,客戶端發(fā)送了第一個(gè)請(qǐng)求連接并且沒(méi)有丟失,只是因?yàn)樵诰W(wǎng)絡(luò)結(jié)點(diǎn)中滯留的時(shí)間太長(zhǎng)了,由于TCP的客戶端遲遲沒(méi)有收到確認(rèn)報(bào)文,以為服務(wù)器沒(méi)有收到,此時(shí)重新向服務(wù)器發(fā)送這條報(bào)文,此后客戶端和服務(wù)器經(jīng)過(guò)兩次握手完成連接,傳輸數(shù)據(jù),然后關(guān)閉連接。此時(shí)此前滯留的那一次請(qǐng)求連接,網(wǎng)絡(luò)通暢了到達(dá)了服務(wù)器,這個(gè)報(bào)文本該是失效的,但是,兩次握手的機(jī)制將會(huì)讓客戶端和服務(wù)器再次建立連接,這將導(dǎo)致不必要的錯(cuò)誤和資源的浪費(fèi)。
如果采用的是三次握手,就算是那一次失效的報(bào)文傳送過(guò)來(lái)了,服務(wù)端接受到了那條失效報(bào)文并且回復(fù)了確認(rèn)報(bào)文,但是客戶端不會(huì)再次發(fā)出確認(rèn)。由于服務(wù)器收不到確認(rèn),就知道客戶端并沒(méi)有請(qǐng)求連接。
三次握手后確定了滑動(dòng)窗口大小window size以及MSS為TCP最大分段大小,MSS=MTU-TCP首部-IP首部,window size一般都大于MTU

  • 四次揮手
  1. 客戶端進(jìn)程發(fā)出連接釋放報(bào)文,并且停止發(fā)送數(shù)據(jù)。釋放數(shù)據(jù)報(bào)文首部,FIN=1,其序列號(hào)為seq=u(等于前面已經(jīng)傳送過(guò)來(lái)的數(shù)據(jù)的最后一個(gè)字節(jié)的序號(hào)加1),此時(shí),客戶端進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài)。 TCP規(guī)定,F(xiàn)IN報(bào)文段即使不攜帶數(shù)據(jù),也要消耗一個(gè)序號(hào)。
  2. 服務(wù)器收到連接釋放報(bào)文,發(fā)出確認(rèn)報(bào)文,ACK=1,ack=u+1,并且?guī)献约旱男蛄刑?hào)seq=v,此時(shí),服務(wù)端就進(jìn)入了CLOSE-WAIT(關(guān)閉等待)狀態(tài)。TCP服務(wù)器通知高層的應(yīng)用進(jìn)程,客戶端向服務(wù)器的方向就釋放了,這時(shí)候處于半關(guān)閉狀態(tài),即客戶端已經(jīng)沒(méi)有數(shù)據(jù)要發(fā)送了,但是服務(wù)器若發(fā)送數(shù)據(jù),客戶端依然要接受。這個(gè)狀態(tài)還要持續(xù)一段時(shí)間,也就是整個(gè)CLOSE-WAIT狀態(tài)持續(xù)的時(shí)間。
  3. 客戶端收到服務(wù)器的確認(rèn)請(qǐng)求后,此時(shí),客戶端就進(jìn)入FIN-WAIT-2(終止等待2)狀態(tài),等待服務(wù)器發(fā)送連接釋放報(bào)文(在這之前還需要接受服務(wù)器發(fā)送的最后的數(shù)據(jù))。
  4. 服務(wù)器將最后的數(shù)據(jù)發(fā)送完畢后,就向客戶端發(fā)送連接釋放報(bào)文,F(xiàn)IN=1,ack=u+1,由于在半關(guān)閉狀態(tài),服務(wù)器很可能又發(fā)送了一些數(shù)據(jù),假定此時(shí)的序列號(hào)為seq=w,此時(shí),服務(wù)器就進(jìn)入了LAST-ACK(最后確認(rèn))狀態(tài),等待客戶端的確認(rèn)。
  5. 客戶端收到服務(wù)器的連接釋放報(bào)文后,必須發(fā)出確認(rèn),ACK=1,ack=w+1,而自己的序列號(hào)是seq=u+1,此時(shí),客戶端就進(jìn)入了TIME-WAIT(時(shí)間等待)狀態(tài)。注意此時(shí)TCP連接還沒(méi)有釋放,必須經(jīng)過(guò)2MSL(最長(zhǎng)報(bào)文段壽命)的時(shí)間后,當(dāng)客戶端撤銷相應(yīng)的TCB后,才進(jìn)入CLOSED狀態(tài)。
  6. 服務(wù)器只要收到了客戶端發(fā)出的確認(rèn),立即進(jìn)入CLOSED狀態(tài)。同樣,撤銷TCB后,就結(jié)束了這次的TCP連接??梢钥吹?,服務(wù)器結(jié)束TCP連接的時(shí)間要比客戶端早一些。

    為什么客戶端最后還要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允許不同的實(shí)現(xiàn)可以設(shè)置不同的MSL值。
第一,保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文能夠到達(dá)服務(wù)器,因?yàn)檫@個(gè)ACK報(bào)文可能丟失,站在服務(wù)器的角度看來(lái),我已經(jīng)發(fā)送了FIN+ACK報(bào)文請(qǐng)求斷開了,客戶端還沒(méi)有給我回應(yīng),應(yīng)該是我發(fā)送的請(qǐng)求斷開報(bào)文它沒(méi)有收到,于是服務(wù)器又會(huì)重新發(fā)送一次,而客戶端就能在這個(gè)2MSL時(shí)間段內(nèi)收到這個(gè)重傳的報(bào)文,接著給出回應(yīng)報(bào)文,并且會(huì)重啟2MSL計(jì)時(shí)器。
第二,防止類似與“三次握手”中提到了的“已經(jīng)失效的連接請(qǐng)求報(bào)文段”出現(xiàn)在本連接中??蛻舳税l(fā)送完最后一個(gè)確認(rèn)報(bào)文后,在這個(gè)2MSL時(shí)間中,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。這樣新的連接中不會(huì)出現(xiàn)舊連接的請(qǐng)求報(bào)文。

為什么建立連接是三次握手,關(guān)閉連接確是四次揮手呢?
建立連接的時(shí)候, 服務(wù)器在LISTEN狀態(tài)下,收到建立連接請(qǐng)求的SYN報(bào)文后,把ACK和SYN放在一個(gè)報(bào)文里發(fā)送給客戶端。
而關(guān)閉連接時(shí),服務(wù)器收到對(duì)方的FIN報(bào)文時(shí),僅僅表示對(duì)方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù),而自己也未必全部數(shù)據(jù)都發(fā)送給對(duì)方了,所以己方可以立即關(guān)閉,也可以發(fā)送一些數(shù)據(jù)給對(duì)方后,再發(fā)送FIN報(bào)文給對(duì)方來(lái)表示同意現(xiàn)在關(guān)閉連接,因此,己方ACK和FIN一般都會(huì)分開發(fā)送,從而導(dǎo)致多了一次。

如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦?

TCP還設(shè)有一個(gè)?;钣?jì)時(shí)器,顯然,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去,白白浪費(fèi)資源。服務(wù)器每收到一次客戶端的請(qǐng)求后都會(huì)重新復(fù)位這個(gè)計(jì)時(shí)器,時(shí)間通常是設(shè)置為2小時(shí),若兩小時(shí)還沒(méi)有收到客戶端的任何數(shù)據(jù),服務(wù)器就會(huì)發(fā)送一個(gè)探測(cè)報(bào)文段,以后每隔75分鐘發(fā)送一次。若一連發(fā)送10個(gè)探測(cè)報(bào)文仍然沒(méi)反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接。

四、超時(shí)重傳

TCP提供可靠的傳輸層。它使用的方法就是確認(rèn)從另一端收到的數(shù)據(jù)。但數(shù)據(jù)和確認(rèn)都有可能會(huì)丟失。TCP通過(guò)在發(fā)送時(shí)設(shè)置一個(gè)定時(shí)器來(lái)解決這個(gè)問(wèn)題。如果當(dāng)定時(shí)器溢出時(shí)還沒(méi)收到ack確認(rèn),則進(jìn)行重傳。

對(duì)于每個(gè)連接,TCP管理4個(gè)不同的定時(shí)器:

  1. 重傳定時(shí)器使用于當(dāng)希望收到另一端的確認(rèn)。
  2. 堅(jiān)持(persist)定時(shí)器使窗口大小信息保持不斷流動(dòng),即使另一端關(guān)閉了其接收窗口。
  3. ?;? keepalive)定時(shí)器可檢測(cè)到一個(gè)空閑連接的另一端何時(shí)崩潰或重啟。
  4. 2MSL定時(shí)器測(cè)量一個(gè)連接處于TIME_WATE狀態(tài)的時(shí)間,斷開連接時(shí)使用。

重傳機(jī)制在實(shí)現(xiàn)數(shù)據(jù)可靠傳輸功能的同時(shí),也引起了相應(yīng)的性能問(wèn)題:何時(shí)進(jìn)行數(shù)據(jù)重傳?如何保證較高的傳輸效率?

重傳時(shí)間過(guò)短:在網(wǎng)絡(luò)因?yàn)閾砣饋G包時(shí),頻繁的重傳會(huì)進(jìn)一步加劇網(wǎng)絡(luò)擁塞,引起丟包,惡化網(wǎng)絡(luò)傳輸性能。

重傳時(shí)間過(guò)長(zhǎng):接收方長(zhǎng)時(shí)間無(wú)法完成數(shù)據(jù)接收,引起長(zhǎng)時(shí)間占用連接線路造成資源損耗、傳輸效率較低等問(wèn)題。

針對(duì)上述問(wèn)題,TCP中設(shè)計(jì)了超時(shí)重傳機(jī)制。該機(jī)制規(guī)定當(dāng)發(fā)送方A向B發(fā)送數(shù)據(jù)包P1時(shí),開啟一個(gè)時(shí)長(zhǎng)為RTO(Retransmission Timeout)的重傳定時(shí)器,如果A在RTO內(nèi)未收到B對(duì)P1的確認(rèn)報(bào)文,則認(rèn)為P1在網(wǎng)絡(luò)中丟失,此時(shí)重新發(fā)送P1。由此,引出RTO大小的設(shè)定問(wèn)題。

對(duì)RTO大小的設(shè)定,由于的傳輸特性不同將導(dǎo)致發(fā)送與接收方完成一次數(shù)據(jù)傳輸(發(fā)送與應(yīng)答)的時(shí)間不同(例:通常有線網(wǎng)絡(luò)的傳輸速率遠(yuǎn)高于無(wú)線網(wǎng)絡(luò)),因此固定大小的RTO無(wú)法滿足不同環(huán)境下的傳輸需求,由此TCP采用針對(duì)具體傳輸環(huán)境動(dòng)態(tài)測(cè)量的方式來(lái)確定當(dāng)前時(shí)刻的RTO.

針對(duì)上述問(wèn)題TCP中引入RTT(Round Trip Time),其中RTT為一個(gè)數(shù)據(jù)包從發(fā)出去到收到對(duì)該包確認(rèn)的時(shí)間差,并根據(jù)RTT計(jì)算RTO.

五、Nagle算法

這里不對(duì)nagle算法做詳細(xì)的講解,只討論它的作用和意義

TCP/IP協(xié)議中,無(wú)論發(fā)送多少數(shù)據(jù),總是要在數(shù)據(jù)前面加上協(xié)議頭,同時(shí),對(duì)方接收到數(shù)據(jù),也需要發(fā)送ACK表示確認(rèn)。為了盡可能的利用網(wǎng)絡(luò)帶寬,TCP總是希望盡可能的發(fā)送足夠大的數(shù)據(jù)。(一個(gè)連接會(huì)設(shè)置MSS參數(shù),因此,TCP/IP希望每次都能夠以MSS尺寸的數(shù)據(jù)塊來(lái)發(fā)送數(shù)據(jù))。Nagle算法就是為了盡可能發(fā)送大塊數(shù)據(jù),避免網(wǎng)絡(luò)中充斥著許多小數(shù)據(jù)塊。(減少大量小包的發(fā)送)

Nagle算法的基本定義是任意時(shí)刻,最多只能有一個(gè)未被確認(rèn)的小段。所謂“小段”,指的是小于MSS尺寸的數(shù)據(jù)塊,所謂“未被確認(rèn)”,是指一個(gè)數(shù)據(jù)塊發(fā)送出去后,沒(méi)有收到對(duì)方發(fā)送的ACK確認(rèn)該數(shù)據(jù)已收到。

六、Tcp粘包問(wèn)題

首先我們要知道,數(shù)據(jù)在進(jìn)行網(wǎng)絡(luò)傳輸時(shí),是從頂層協(xié)議開始對(duì)數(shù)據(jù)添加報(bào)頭的。
什么時(shí)候會(huì)出現(xiàn)TCP粘包?

  1. 如果利用tcp每次發(fā)送數(shù)據(jù),就與對(duì)方建立連接,然后雙方發(fā)送完一段數(shù)據(jù)后,就關(guān)閉連接,這樣就不會(huì)出現(xiàn)粘包問(wèn)題(因?yàn)橹挥幸环N包結(jié)構(gòu),類似于http協(xié)議)。關(guān)閉連接主要要雙方都發(fā)送close連接(參考tcp關(guān)閉協(xié)議)。如:A需要發(fā)送一段字符串給B,那么A與B建立連接,然后發(fā)送雙方都默認(rèn)好的協(xié)議字符如"hello give me sth abour yourself",然后B收到報(bào)文后,就將緩沖區(qū)數(shù)據(jù)接收,然后關(guān)閉連接,這樣粘包問(wèn)題不用考慮到,因?yàn)榇蠹叶贾朗前l(fā)送一段字符。
  2. 如果發(fā)送數(shù)據(jù)無(wú)結(jié)構(gòu),如文件傳輸,這樣發(fā)送方只管發(fā)送,接收方只管接收存儲(chǔ)就ok,也不用考慮粘包
  3. 如果雙方建立連接,需要在連接后一段時(shí)間內(nèi)發(fā)送不同結(jié)構(gòu)數(shù)據(jù),如連接后,有好幾種結(jié)構(gòu):
    1)"hello give me sth abour yourself"
    2)"Don't give me sth abour yourself"
    那這樣的話,如果發(fā)送方連續(xù)發(fā)送這個(gè)兩個(gè)包出去,接收方一次接收可能會(huì)是"hello give me sth abour yourselfDon't give me sth abour yourself" 這樣接收方就傻了,到底是要干嘛?不知道,因?yàn)閰f(xié)議沒(méi)有規(guī)定這么詭異的字符串,所以要處理把它分包,怎么分也需要雙方組織一個(gè)比較好的包結(jié)構(gòu),所以一般可能會(huì)在頭加一個(gè)數(shù)據(jù)長(zhǎng)度之類的包,以確保接收。

粘包出現(xiàn)的原因

  • 發(fā)送端需要等緩沖區(qū)滿才發(fā)送出去,造成粘包
  • 接收方不及時(shí)處理緩沖區(qū)的包,造成多個(gè)包接收

接收端需要對(duì)粘包的數(shù)據(jù)進(jìn)行拆包處理,在包的前面添加包頭(或者在包的尾部添加),我們稱之為封包。這樣可以有效的將疊加數(shù)據(jù)區(qū)分開來(lái)

七、滑動(dòng)窗口法

滑動(dòng)窗口實(shí)現(xiàn)了TCP流量控制。網(wǎng)絡(luò)傳輸中會(huì)有這樣一種情況,接收端的緩存數(shù)據(jù)要發(fā)送給應(yīng)用層,而如果發(fā)送端的發(fā)送速率過(guò)快則會(huì)導(dǎo)致接收端的緩存溢出。
接收端和發(fā)送端分別維護(hù)一個(gè)發(fā)送窗口和一個(gè)接收窗口。各自的接收窗口大小取決于應(yīng)用、系統(tǒng)、硬件的限制

窗口的概念
  • 發(fā)送方的緩存數(shù)據(jù)可以分為四類:
  1. 已發(fā)送,已收到ACK
  2. 已發(fā)送,未收到ACK
  3. 未發(fā)送,但允許發(fā)送
  4. 未發(fā)送,但不允許發(fā)送
  • 接收方的緩存數(shù)據(jù)分為3類:
  1. 已接收
  2. 未接收,但準(zhǔn)備接收
  3. 未接收而且不準(zhǔn)備接收
滑動(dòng)機(jī)制
  1. 發(fā)送窗口只有收到發(fā)送窗口內(nèi)字節(jié)的ACK確認(rèn)(下一個(gè)期望的序列號(hào)),才會(huì)移動(dòng)發(fā)送窗口的左邊界
  2. 接收窗口只有在前面所有的幀都確認(rèn)的情況下才會(huì)移動(dòng)左邊界。當(dāng)在前面還有幀未接收但收到后面幀的情況下,窗口不會(huì)移動(dòng),并不會(huì)對(duì)后續(xù)字節(jié)確認(rèn)(這里判斷幀的順序用的是序列號(hào))
  3. 確定了window size,表示一次最多發(fā)送多少字節(jié)

八、擁塞控制

網(wǎng)絡(luò)中的鏈路容量和交換結(jié)點(diǎn)中的緩存和處理機(jī)都有著工作的極限,當(dāng)網(wǎng)絡(luò)的需求超過(guò)它們的工作極限時(shí),就出現(xiàn)了擁塞。擁塞控制就是防止過(guò)多的數(shù)據(jù)注入到網(wǎng)絡(luò)中,這樣可以使網(wǎng)絡(luò)中的路由器或鏈路不致過(guò)載。常用的方法就是:

  1. 慢開始、擁塞控制
  2. 快重傳、快恢復(fù)
  • 慢開始和擁塞控制的步驟
  1. 發(fā)送方維持一個(gè)叫做“擁塞窗口”的變量,該變量和接收端口共同決定了發(fā)送者的發(fā)送窗口(發(fā)送方讓自己的發(fā)送窗口等于擁塞窗口,另外考慮到接受方的接收能力,發(fā)送窗口可能小于擁塞窗口。);

  2. 當(dāng)主機(jī)開始發(fā)送數(shù)據(jù)時(shí),避免一下子將大量字節(jié)注入到網(wǎng)絡(luò),造成或者增加擁塞,選擇發(fā)送一個(gè)1字節(jié)的試探報(bào)文;

  3. 當(dāng)收到第一個(gè)字節(jié)的數(shù)據(jù)的確認(rèn)后,就發(fā)送2個(gè)字節(jié)的報(bào)文;

  4. 若再次收到2個(gè)字節(jié)的確認(rèn),則發(fā)送4個(gè)字節(jié),依次遞增2的指數(shù)級(jí);

  5. 最后會(huì)達(dá)到一個(gè)提前預(yù)設(shè)的“慢開始門限”,比如24,即一次發(fā)送了24個(gè)分組,此時(shí)遵循下面的條件判定:
    *1. cwnd < ssthresh, 繼續(xù)使用慢開始算法;
    *2. cwnd > ssthresh,停止使用慢開始算法,改用擁塞避免算法;
    *3. cwnd = ssthresh,既可以使用慢開始算法,也可以使用擁塞避免算法;

  6. 所謂擁塞避免算法就是:發(fā)送方的擁塞窗口+1(不進(jìn)行指數(shù)級(jí)增長(zhǎng)),即讓擁塞窗口緩慢地增大,按照線性規(guī)律增長(zhǎng);

  7. 當(dāng)出現(xiàn)網(wǎng)絡(luò)擁塞,比如丟包時(shí),將慢開始門限設(shè)為原先的一半,然后將cwnd設(shè)為1,執(zhí)行慢開始算法(較低的起點(diǎn),指數(shù)級(jí)增長(zhǎng));

  • 快重傳的機(jī)制

-1. 接收方建立這樣的機(jī)制,如果一個(gè)包丟失,則對(duì)后續(xù)的包繼續(xù)發(fā)送針對(duì)該包的重傳請(qǐng)求;
-2. 一旦發(fā)送方接收到三個(gè)一樣的確認(rèn),就知道該包之后出現(xiàn)了錯(cuò)誤,立刻重傳該包
-3. 此時(shí)發(fā)送方開始執(zhí)行“快恢復(fù)”算法:
*1. 慢開始門限減半;
*2. cwnd設(shè)為慢開始門限減半后的數(shù)值;
*3. 執(zhí)行擁塞避免算法(高起點(diǎn),線性增長(zhǎng));

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 傳輸層提供的服務(wù) 傳輸層的功能 從通信和信息處理的角度看 ,傳輸層向它上面的應(yīng)用層提供通信服務(wù),它屬于面向通信部分...
    CodeKing2017閱讀 3,802評(píng)論 1 9
  • 17.1 引言 本章將介紹TCP為應(yīng)用層提供的服務(wù),以及TCP首部中的各個(gè)字段。隨后的幾章我們?cè)诹私釺CP的工作過(guò)...
    張芳濤閱讀 608評(píng)論 0 3
  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,390評(píng)論 6 174
  • 當(dāng) app 和服務(wù)器進(jìn)行通信的時(shí)候,大多數(shù)情況下,都是采用 HTTP 協(xié)議。HTTP 最初是為 web 瀏覽器而定...
    Flysss1219閱讀 1,447評(píng)論 0 4
  • 個(gè)人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,215評(píng)論 0 8

友情鏈接更多精彩內(nèi)容