中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

30張圖(tu)說(shuo)清楚 TCP 協議(yi)

大家好,我是風箏

前兩天分享了 20張圖說清楚 IP 協議

今天,繼續(xu)來網管的自我(wo)修養(yang)之TCP協議,這可(ke)是(shi)除 IP 協議外(wai)另一個(ge)核心協議了。

TCP 協(xie)(xie)議是網絡傳(chuan)輸(shu)(shu)(shu)中至(zhi)關重要的(de)(de)(de)一個協(xie)(xie)議,它位于(yu)傳(chuan)輸(shu)(shu)(shu)層。向上支持 FTP、TELNET、SMTP、DNS、HTTP等常見的(de)(de)(de)應用層協(xie)(xie)議,向下要與網絡層的(de)(de)(de) IP 協(xie)(xie)議相互配合(he),實現可靠(kao)的(de)(de)(de)網絡傳(chuan)輸(shu)(shu)(shu)。

分層網絡模型

OSI 7層模型

為了讓全世界的計算機有效的互聯起來,國際標準化組織提出了一種概念化的網絡模型,開放式系統互聯模型(Open System Interconnection Model),簡(jian)稱 OSI 模(mo)型。

自上而下依次為應用層(ceng)(ceng)、表示層(ceng)(ceng)、會話層(ceng)(ceng)、傳輸(shu)層(ceng)(ceng)、網絡層(ceng)(ceng)、數據鏈路層(ceng)(ceng)、物理層(ceng)(ceng)。

應用層

應(ying)(ying)用(yong)層提供為應(ying)(ying)用(yong)軟件而設計的接口,以設置(zhi)與另一(yi)應(ying)(ying)用(yong)軟件之間的通信(xin)。例如:HTTP、HTTPS、FTP、Telnet、SSH、SMTP、POP3等。

表示層

表示層(ceng)把數據(ju)轉換為能(neng)與(yu)接收(shou)者的系統格式(shi)兼(jian)容并適合傳輸的格式(shi)。

會話層

會話(hua)層(ceng)負(fu)責在數據傳輸(shu)中(zhong)設置和維護計(ji)算(suan)機(ji)網絡中(zhong)兩臺計(ji)算(suan)機(ji)之間的通(tong)信(xin)連接。

傳輸層

傳輸(shu)(shu)層(ceng)把(ba)傳輸(shu)(shu)表(biao)頭(TH)加至數據(ju)以形成數據(ju)包。傳輸(shu)(shu)表(biao)頭包含了所使用(yong)的協議等發送信息。例(li)如:傳輸(shu)(shu)控(kong)制協議(TCP)等。

網絡層

網絡層決定數據的路徑(jing)選擇和轉寄,將(jiang)網絡表頭(NH)加至數據包(bao),以形成分組。網絡表頭包(bao)含了網絡資料(liao)。例如:互(hu)聯網協議(IP)等。

數據鏈路層

數據鏈路層負(fu)責網(wang)絡(luo)尋(xun)址(zhi)、錯誤偵測和(he)改錯。當表(biao)頭(tou)和(he)表(biao)尾被(bei)加至(zhi)數據包(bao)時,會形成(cheng)信息框(kuang)。數據鏈表(biao)頭(tou)(DLH)是(shi)包(bao)含了(le)物理地址(zhi)和(he)錯誤偵測及(ji)改錯的(de)方法。數據鏈表(biao)尾(DLT)是(shi)一串(chuan)指示數據包(bao)末端的(de)字(zi)符(fu)串(chuan)。例如(ru)以太網(wang)、無線局域網(wang)(Wi-Fi)和(he)通用分(fen)組(zu)無線服務(GPRS)等。

分(fen)為兩個(ge)子(zi)層(ceng):邏輯鏈(lian)路(lu)控制(logical link control,LLC)子(zi)層(ceng)和介質訪問控制(Media access control,MAC)子(zi)層(ceng)。

物理層

物理層在局(ju)部局(ju)域網上(shang)傳送(song)數據幀,它負責管理電腦通信(xin)設備和網絡媒(mei)體之(zhi)間的互通。包括了針腳、電壓、線(xian)纜規范、集線(xian)器、中(zhong)繼器、網卡、主機接口(kou)卡等。

OSI 模(mo)(mo)型是國際(ji)標準(zhun)(zhun)模(mo)(mo)型,是指導互聯(lian)網(wang)模(mo)(mo)型的概念標準(zhun)(zhun)。而(er)在實際(ji)的設計實現過程中,最后(hou)形成(cheng)了 TCP/IP 4層模(mo)(mo)型結構(gou)。

TCP/IP 4層模型

TCP/IP 模型(xing)實際(ji)上并不單單指 TCP 和 IP,實際(ji)上這一個(ge)協議(yi)簇(cu),還包含了其他的一些協議(yi),比如 UDP、ICMP、IGMP 等。

TCP/IP 模(mo)(mo)(mo)型是事(shi)實上(shang)的標準模(mo)(mo)(mo)型,在 7 層模(mo)(mo)(mo)型的基礎上(shang)將最上(shang)面三層的應用層、表示層、會話(hua)層統(tong)一(yi)為(wei)應用層,將數據鏈路層和物理(li)層統(tong)一(yi)為(wei)鏈路層或者叫網絡接口層。

實際應用中(zhong)還是(shi)以 4 層(ceng)(ceng)模型為(wei)準,畢竟這才是(shi)事實上(shang)的標準。還有一種 5 層(ceng)(ceng)模型的說法,實際上(shang)就(jiu)是(shi)把 7 層(ceng)(ceng)中(zhong)的應用層(ceng)(ceng)、表示(shi)層(ceng)(ceng)、會(hui)話層(ceng)(ceng)合并(bing)為(wei)應用層(ceng)(ceng),其他(ta)層(ceng)(ceng)保持不變。

數據的加工和傳輸過程

TCP/IP 模型每個層都有各(ge)自的(de)功能和分工,當有用戶數(shu)據想(xiang)要發(fa)送給另(ling)一臺設備的(de)時候,數(shu)據自上而下(xia),從應用層向鏈路層傳遞有一個復雜的(de)過程。

以 Telnet 為(wei)例,Telnet 在傳輸層是使用(yong) TCP 協議的。

數(shu)(shu)據(ju)從應用層(ceng)進入,到達傳輸層(ceng),添加(jia)上 TCP首部,將數(shu)(shu)據(ju)加(jia)工成 TCP 段,稱為 Segment。這是為了(le)保(bao)證(zheng)數(shu)(shu)據(ju)的(de)可靠性。

接(jie)著數據(ju)到達網絡層(ceng),在網絡層(ceng)使用 IP 協議,被添加上 IP 首部(bu),將數據(ju)加工成 IP數據(ju)報,稱為 datagram 。經過網絡層(ceng) IP 協議的加工,指定(ding)目標(biao)地址和 MAC 地址,保證(zheng)數據(ju)準(zhun)確的發送(song)到目標(biao)機器。

接著數據到達鏈路層,添加(jia)(jia)上以太(tai)網(wang)(wang)(wang)頭部(bu),將數據加(jia)(jia)工成以太(tai)網(wang)(wang)(wang)幀,稱為 frame,包含了網(wang)(wang)(wang)卡(ka)等硬件相關的數據。

無(wu)論(lun)是 Telnet 還(huan)是 HTTP,都至少涉及到(dao)兩(liang)臺(tai)設備才能(neng)稱之(zhi)為(wei)網絡(luo)互連,那(nei)發送方有(you)一個數據(ju)自(zi)應(ying)用層向(xiang)底層鏈路(lu)(lu)層的(de)(de)加工過程(cheng),對應(ying)的(de)(de),在數據(ju)接(jie)收(shou)方,有(you)一個數據(ju)從鏈路(lu)(lu)層向(xiang)應(ying)用層解析(xi)的(de)(de)過程(cheng)。這中間(jian)可(ke)能(neng)經歷了漫(man)長(chang)的(de)(de)傳輸(shu)介(jie)質,比(bi)(bi)如(ru)光纖,還(huan)可(ke)能(neng)有(you)若干個中間(jian)設備,比(bi)(bi)如(ru)路(lu)(lu)由(you)器、交換機等等。要(yao)保(bao)證數據(ju)在這么復雜的(de)(de)網絡(luo)環境(jing)中可(ke)靠、準確的(de)(de)發送到(dao)目(mu)標機器,就是靠的(de)(de) TCP、IP協議精(jing)巧的(de)(de)設計。

TCP 協議

TCP,全稱是 Transmission Control Protocol,傳輸控(kong)制協(xie)(xie)議(yi)。 是一種(zhong)面(mian)向連(lian)接(jie)的(de)、可(ke)靠的(de)字節流服務協(xie)(xie)議(yi),正因(yin)為它要(yao)(yao)保證可(ke)靠性,所(suo)以比(bi)起 UDP 協(xie)(xie)議(yi)要(yao)(yao)復雜的(de)多,正是由于這種(zhong)復雜性,導致它的(de)性能比(bi) UDP 差。

TCP 是(shi) TCP/IP 模型(xing)中(zhong)(zhong)的(de)傳輸(shu)層(ceng)一個(ge)最核(he)心的(de)協議,不(bu)僅如此,在整個(ge) 4 層(ceng)模型(xing)中(zhong)(zhong),它(ta)都是(shi)核(he)心的(de)協議,要不(bu)然模型(xing)怎么(me)會叫做 TCP/IP 模型(xing)呢(ni)。

它向下使用(yong)網絡層的(de) IP 協(xie)(xie)(xie)議,向上為 FTP、SMTP、POP3、SSH、Telnet、HTTP 等應用(yong)層協(xie)(xie)(xie)議提供支(zhi)持。其他的(de)還有我(wo)們常(chang)用(yong)的(de) Redis 的(de) RESP 協(xie)(xie)(xie)議、MongoDB的(de)網絡協(xie)(xie)(xie)議,以及(ji)我(wo)們編程中用(yong)到的(de) Socket,都是 TCP 協(xie)(xie)(xie)議在(zai)背后提供支(zhi)持的(de)。

網絡協議是(shi)通信計算機雙方必須共同遵(zun)從的(de)一組(zu)約(yue)定(ding)。如怎么樣(yang)建(jian)立連接、怎么樣(yang)互相識(shi)別(bie)等。只有遵(zun)守這個約(yue)定(ding),計算機之間才能相互通信交(jiao)流。它的(de)三要素是(shi):語(yu)(yu)法(fa)、語(yu)(yu)義、時序。

  1. 語法:即(ji)數據與控(kong)制信息的結構(gou)或(huo)格式(shi);

  2. 語義(yi):即需要發(fa)出何(he)種(zhong)控制信息,完成(cheng)何(he)種(zhong)動(dong)作以及做出何(he)種(zhong)響應;

  3. 時序(xu)(同步):即事件實現順序(xu)的詳細(xi)說明(ming)。

TCP 協議格式

TCP首部(bu) + 用戶(hu)數據被稱為TCP段(duan),其中 TCP 首部(bu)就是這(zhe)里要主要研(yan)究的(de) TCP 協議的(de)核心所(suo)在,用戶(hu)數據部(bu)分是 TCP 段(duan)的(de)負載。

TCP 段的(de)大小也是有限制的(de),最大是 1460 字節(jie),這是怎么算出的(de)呢?

最終(zhong)由(you)網卡發出(chu)去的數(shu)據包叫(jiao)做以(yi)太網幀,以(yi)太網幀由(you)以(yi)太網首(shou)部和負載構成。

以太(tai)網幀的負載(zai)就(jiu)是一個 IP 數據報(bao),IP數據報(bao)由IP首部和負載(zai)構(gou)成。

IP數據(ju)報的負載(zai)就(jiu)是一個 TCP段。所以(yi),TCP段所能搭載(zai)的最(zui)大數據(ju)量可(ke)以(yi)這樣(yang)計算出(chu)來:

$TCP段搭載(zai)的數據大小(xiao) = 以(yi)太網(wang)幀大小(xiao)-以(yi)太網(wang)首(shou)部-IP首(shou)部-TCP首(shou)部$

以太網幀的(de)(de)大小是(shi)固(gu)定(ding)的(de)(de) 1522字(zi)節(jie)(jie),而(er)IP首(shou)部(bu)和TCP首(shou)部(bu)的(de)(de)大小是(shi)不固(gu)定(ding)的(de)(de),但是(shi)最少會各占20字(zi)節(jie)(jie),所以最后算下來 TCP段搭載的(de)(de)數據(ju)大小最多為 1460字(zi)節(jie)(jie)。

$TCP段搭載的數(shu)據(ju)大小(xiao)(最多(duo)1460) = 以太網幀(zhen)大小(xiao)(1522字節)-以太網首部(bu)(bu)(22字節)-IP首部(bu)(bu)(最少(shao)20字節)-TCP首部(bu)(bu)(最少(shao)20字節)$

下圖是TCP協議的示意圖,如果不算「可選項」部分的話,共占用 32bit x 5 = 160bit,也就是(shi)20個字節。

源端口和目標端口

源端(duan)口(kou)(kou)和(he)目(mu)標(biao)端(duan)口(kou)(kou)分別占(zhan)用 2個(ge)(ge)字節,共(gong)占(zhan)用 4 字節,分別記錄數(shu)據(ju)發送端(duan)的(de)(de)(de)端(duan)口(kou)(kou)號和(he)數(shu)據(ju)接(jie)(jie)收端(duan)的(de)(de)(de)端(duan)口(kou)(kou)號,這兩個(ge)(ge)標(biao)記和(he) IP 協議中記錄的(de)(de)(de)發送端(duan) IP 和(he)接(jie)(jie)收端(duan) IP組合起來(lai),便可確定(ding)一個(ge)(ge)唯一的(de)(de)(de) TCP 連接(jie)(jie)。

序號

由于TCP段(duan)的大小有限制,當(dang)要傳輸的數據量大于這個限制的時候,就要對(dui)數據進行分段(duan),一段(duan)一段(duan)的發送,既然發送方要分段(duan),那接收方就要對(dui)分段(duan)進行重(zhong)(zhong)組,才能還原(yuan)回原(yuan)始(shi)數據。在重(zhong)(zhong)組的過程中(zhong),要保證各段(duan)間的先后順(shun)序(xu),序(xu)號(hao)正是起(qi)到保證重(zhong)(zhong)組順(shun)序(xu)的作用。

序(xu)號占(zhan)用 4 字(zi)節(jie),32 位(wei),它(ta)的(de)范圍(wei)是(shi) [0,$2^{32}$]?。TCP是(shi)字(zi)節(jie)流服務,會(hui)對(dui)每(mei)一(yi)(yi)個發(fa)送的(de)字(zi)節(jie)進行(xing)編號。在(zai)建(jian)立連(lian)(lian)接(jie)(jie)的(de)時(shi)候(hou),系統會(hui)給定一(yi)(yi)個 ISN(初(chu)始序(xu)號),然后這個設備在(zai)當前連(lian)(lian)接(jie)(jie)中發(fa)送的(de)第(di)一(yi)(yi)個字(zi)節(jie)的(de)序(xu)號就是(shi) ISN+1,假設 ISN 初(chu)始為0,那(nei)第(di)一(yi)(yi)個字(zi)節(jie)的(de)序(xu)號就是(shi) 1。

舉(ju)個(ge)例子,假設ISN為(wei)0,發(fa)(fa)送(song)(song)端第一次發(fa)(fa)送(song)(song) 100 字節的(de)數據(ju)(ju)包(bao),那(nei)這第一個(ge) TCP段的(de)序號就(jiu)是1,下次再發(fa)(fa)送(song)(song) 100字節的(de)數據(ju)(ju)包(bao),那(nei)這第二(er)個(ge) TCP段的(de)序號就(jiu)是 101。

這(zhe)樣一來,最大可(ke)以一直(zhi)標記 $2^{32}$個(ge)字節,也就(jiu)是(shi) 4個(ge)G的數據。當達到最大值后,又會從 0 開始標記。

序號只有在下面(mian)兩種情況下才(cai)有用:

  1. 數據字段至少包含一個字節。
  2. 是一個 SYN 段,或者是 FIN 段,或者是 RST 段。

確認序號

當數據(ju)發(fa)送(song)出去,接收方(fang)收到之后,會回(hui)復一個(ge)確(que)認序號回(hui)復給發(fa)送(song)方(fang),這個(ge)確(que)認序號表示接收方(fang)希(xi)望下次接收的(de)(de)(de)序號。例(li)如發(fa)送(song)了序號為501的(de)(de)(de),長度為100的(de)(de)(de)TCP段,那接收方(fang)收到后要(yao)回(hui)復 601的(de)(de)(de)確(que)認序號,表示【0-600】的(de)(de)(de)字節已(yi)經(jing)接收,下次希(xi)望收到第 601個(ge)字節以后的(de)(de)(de)數據(ju)。

為了提高效率(lv),并不(bu)是每(mei)次(ci)接收(shou)到(dao)TCP段都會馬上(shang)回復給發(fa)送方(fang)(fang),而是采(cai)用累積確認的(de)方(fang)(fang)式,即每(mei)傳(chuan)送多個連續 TCP 段,可以只(zhi)對最后一(yi)個 TCP 段進行(xing)確認。

確認序號只有在 ACK 標(biao)志位被設置的(de)時候才有效。

首部長度

之所以需要首部長度,是因為可選項的大小是不固定的,如果沒有可選項的話,那首部長度就是 20字節。這個標示部分占 4 bit,單位是4字節,4bit 可表示的最大值是 15,一個單位表示的長度是4字節,所以首部長度最大可以是 15 x 4字節,也就是 60 字(zi)節。

保留

顧(gu)名思(si)義,是保留(liu)位,占(zhan)用6個比特(te)位,目前的值為 0。

6個標志位

協議中有 6 個比特標記位,可(ke)以理(li)解為(wei) TCP 段的類(lei)型。

URG

1個比特(te)位,當(dang)被(bei)設置為1時,表明緊(jin)急指針字段(duan)有效(xiao),該報文段(duan)有緊(jin)急數據(ju),應(ying)盡快發送(song)。

ACK

當 ACK 設置為(wei)1時,確認號才(cai)有效,連接建立后(hou),所有的報文段ACK都為(wei) 1。

PSH

當 PSH 設置為1時,接(jie)收方應該盡快將這個(ge)報文段交給應用層,而不(bu)再等待整(zheng)個(ge)緩存填滿再交付(fu)。

RST

當 RST 為(wei)1時,表(biao)示連接(jie)出現嚴重錯誤,必須重新建立連接(jie)。

SYN

在建立連接時用到。

當SYN=1,ACK=0時(shi),表明這是一個連(lian)接請求報文段(duan)。

當SYN=1,ACK=1時,表明對(dui)方(fang)同意連(lian)接。

FIN

用來釋放一個連接(jie)窗口。當FIN=1時,表明此報(bao)文段的發送方不再(zai)發送數據,請求釋放單向(xiang)連接(jie)。TCP斷開連接(jie)用到。

窗口大小

大小為(wei)2個字節(jie),表示(shi)發送方(fang)(fang)自己的(de)接收窗(chuang)口,用來告訴對方(fang)(fang)允許(xu)發送的(de)數據量,最大為(wei)65535字節(jie)。

檢驗和

校(xiao)(xiao)驗(yan)(yan)和(he)是(shi)必需的(de),是(shi)一個端到(dao)端的(de)校(xiao)(xiao)驗(yan)(yan)和(he),由(you)發送(song)端計算(suan),然(ran)后由(you)接(jie)收端驗(yan)(yan)證。其目(mu)的(de)是(shi)為了(le)發現TCP首部和(he)數(shu)據(ju)在(zai)發送(song)端到(dao)接(jie)收端之間發生(sheng)的(de)任何(he)改動。如果接(jie)收方檢測到(dao)校(xiao)(xiao)驗(yan)(yan)和(he)有差(cha)錯,則TCP段會被直接(jie)丟棄。

緊急指針

占2字(zi)節,當URG=1時(shi),緊急指(zhi)針表示本報文段中的(de)緊急數(shu)(shu)據的(de)字(zi)節數(shu)(shu),表示從(cong)這個 TCP段的(de)序號開始的(de)后的(de)若干個字(zi)節是緊急數(shu)(shu)據,之后的(de)就是普(pu)通數(shu)(shu)據。

假(jia)設此TCP段的序號為(wei)101,緊急指(zhi)針為(wei)30,那就表示從 101開始,直到 131,【101,131】這個區間(jian)內為(wei)緊急數據(ju)。

三次握手和四次揮手

數據要(yao)完(wan)成傳輸,必須要(yao)建立連(lian)接。由于建立TCP連(lian)接的過程需要(yao)來回3次,所以(yi),將這(zhe)個(ge)過程形象的叫(jiao)做三次握(wo)手。

而連接斷開的(de)時候要經過四(si)次(ci)數據傳輸,所以也被稱(cheng)為4次(ci)揮手。

啥都別說(shuo)了,先(xian)看(kan)圖吧。

三次握手,建立連接

結合上面的圖來(lai)看更(geng)清楚。

先(xian)說三次握(wo)手(shou)吧,連(lian)接是后續數(shu)據(ju)傳輸的基礎。就像我(wo)們(men)(men)打電話(hua)一(yi)樣,必須保(bao)證我(wo)和對方都拿著電話(hua)在聽,才能保(bao)證我(wo)們(men)(men)兩個說的話(hua)對方能夠接收(shou)到。

三(san)次握手(shou)大(da)概就是這(zhe)個意(yi)思:

張三(san)想跟李四(si)聊(liao)聊(liao)天,于是(shi)張三(san)撥(bo)通了(le)李四(si)的手(shou)機號,李四(si)聽(ting)到(dao)鈴(ling)聲響起,按(an)(an)了(le)接聽(ting)按(an)(an)鈕。

張(zhang)三:Hi,李(li)四,是你嗎?嘮兩塊錢的呀!

李(li)四:Hi,張(zhang)三,是我,可以嘮。

張三:好,我(wo)確定是你(ni)了,接下來我(wo)要開(kai)始和你(ni)嘮了。

看(kan)上去(qu)多(duo)少有點兒死板,但程序上確(que)實就(jiu)是這(zhe)樣(yang)的。

1、第一次握手

首(shou)先客戶(hu)端(duan)發起連(lian)接請(qing)求,向服(fu)務器(qi)發送 TCP段(duan),段(duan)中包含了(le)目標端(duan)口和本機端(duan)口,設置 SYN 標志位為1,序(xu)號為 x,也就(jiu)是(shi)初始序(xu)號 ISN,如(ru)果(guo)是(shi)第一個連(lian)接,很(hen)有(you)可能就(jiu)是(shi) 0。當(dang)然,此(ci)時服(fu)務器(qi)對應的端(duan)口要(yao)處于監聽(ting)狀態(tai)。此(ci)時,客戶(hu)端(duan)進入 SYNC_SENT 狀態(tai),等(deng)待(dai)服(fu)務器(qi)的確認。

2、第二次握手

服(fu)(fu)(fu)務(wu)端(duan)(duan)收到(dao)客戶端(duan)(duan)發(fa)來的 SYN 段(duan),對這個SYN報文(wen)段(duan)進行確認,設置Acknowledgment Number為(wei)x+1(Sequence Number+1),這就是確認序(xu)(xu)號(hao)。同時(shi),服(fu)(fu)(fu)務(wu)端(duan)(duan)還要發(fa)送(song) SYN 請(qing)求信息(xi),將SYN位(wei)置為(wei)1,Sequence Number為(wei) y(服(fu)(fu)(fu)務(wu)端(duan)(duan)的TCP段(duan)序(xu)(xu)號(hao))。服(fu)(fu)(fu)務(wu)器(qi)端(duan)(duan)將上(shang)述所有信息(xi)放到(dao)一(yi)個TCP段(duan)(即SYN+ACK段(duan))中,一(yi)并發(fa)送(song)給客戶端(duan)(duan),此(ci)時(shi)服(fu)(fu)(fu)務(wu)器(qi)進入SYN_RECV狀態。

3、第三次握手

客戶端(duan)接(jie)收到(dao)服務(wu)端(duan)發(fa)來(lai)的 SYN+ACK 段后,發(fa)送一個 ACK 給服務(wu)端(duan),將(jiang) Acknowledgment Number 設置(zhi)為 y+1。此時客戶端(duan)進入 ESTABLISHED(已連(lian)接(jie))狀(zhuang)態,服務(wu)端(duan)接(jie)收到(dao)此 TCP段,也(ye)(ye)將(jiang)進入 ESTABLISHED 狀(zhuang)態,也(ye)(ye)就(jiu)標志(zhi)著三次握手結束(shu),連(lian)接(jie)成(cheng)功(gong)建立。

三(san)次握手完(wan)成之后,連接就(jiu)建(jian)立了(le),之后就(jiu)可以愉(yu)快的傳輸數據(ju)了(le)。

四次揮手,江湖再見

一旦有了(le)感(gan)情(qing)(連接),再分(fen)(fen)手(shou)就難了(le),難到(dao)需要四次(ci)揮手(shou)。不像 UDP 那(nei)樣,沒有連接,說分(fen)(fen)就分(fen)(fen)。

當(dang)客(ke)(ke)戶(hu)端(duan)和服(fu)務(wu)端(duan)雙方(fang)發送數(shu)據完成(cheng)后(hou),一般(ban)會(hui)由(you)客(ke)(ke)戶(hu)端(duan)主動發起(qi)斷開(kai)連接(jie)的請求,當(dang)然,也有少數(shu)情況是(shi)服(fu)務(wu)端(duan)主動發起(qi)。

以最常見的客戶端(duan)發起(qi)斷開連(lian)接為例,說(shuo)一(yi)下四(si)次揮手的過程。

1、第一次揮手

客(ke)戶端(duan)設置序號(Sequence Number)和確認(ren)序號(Acknowledgment Number),發(fa)送(song)一個 FIN 段給服務器。這(zhe)時(shi),客(ke)戶端(duan)進入 FIN_WAIT_1狀態,意味著客(ke)戶端(duan)沒有數據要發(fa)送(song)了。

2、第二次揮手

服務端收到 FIN 報文段(duan),向(xiang)客戶端發送一(yi)個 ACK 段(duan),客戶端進入 FIN_WAIT_2 狀態(tai)。表示服務端已同意連接(jie)關閉請求(qiu)。

3、第三次揮手

服(fu)務端向客(ke)戶端發送 FIN 段,請求(qiu)關(guan)閉(bi)連接,同(tong)時服(fu)務端進入 LAST_ACK 狀(zhuang)態。

4、第四次揮手

客戶端收到服務(wu)端發(fa)來的 FIN 段(duan),向服務(wu)端發(fa)送 ACK 段(duan),之后客戶端進(jin)入TIME_WAIT狀態。服務(wu)端收到客戶端的ACK 段(duan)以后,就(jiu)關閉連接。

上面(mian)就是由客(ke)戶端主動發(fa)起(qi)關閉連接的過程。

半關閉狀態

TCP 是一(yi)個(ge)全雙工的字節流服務,意思就是說(shuo)兩個(ge)端點都可(ke)以(yi)同時發送和(he)接收(shou)消息。

正(zheng)常情(qing)況下需(xu)要(yao)四(si)次揮手才能(neng)完成連接(jie)的完全斷開。但是(shi)有一種情(qing)況是(shi)這樣的,只主動(dong)關閉自己(ji)(ji)到對方的連接(jie),但是(shi)對方還是(shi)可以給自己(ji)(ji)發送數據(ju)。

用 WireShark 抓住 TCP

Wireshark 是幫(bang)助我(wo)們分(fen)析(xi)網絡請求的(de)(de)利(li)器(qi),建議每個(ge)同學(xue)都裝一個(ge)。我(wo)們先用 Wireshark 抓取一個(ge)完整的(de)(de)連接建立、發送(song)數據、斷開連接的(de)(de)過程。

我這兒只簡單(dan)的(de)介紹一下操作流程。

1、首先打(da)開 Wireshark,在歡迎界(jie)面會(hui)列出當前機器上的所(suo)有(you)網(wang)口、虛機網(wang)口等可以抓取的部(bu)件。

2、我接下(xia)來要(yao)用 Telnet 連接一個外(wai)網服(fu)務器,所以我選擇第(di)一個 WI-FI:en0,這樣 Wireshark 就會捕獲我連接的(de) wifi 上的(de)網絡傳輸。

3、我(wo)只想要抓一(yi)下(xia)最簡(jian)單(dan)的(de) TCP 連接、發數(shu)據、斷開(kai)的(de)過程,所以(yi)要做一(yi)下(xia)抓取過濾。Wireshark 中(zhong)的(de)過濾器(qi)可(ke)以(yi)實現(xian)這樣的(de)需求。在下(xia)圖紅框部分可(ke)以(yi)選了一(yi)個過濾器(qi)。

4、因為(wei)當(dang)前(qian)沒有直接可(ke)用的符合要求(qiu)的過濾(lv)器,所以,需要自(zi)己寫(xie)一個。點(dian)擊前(qian)面(mian)的綠(lv)色書簽圖標,然后在彈出窗口(kou)中點(dian)擊加號添加一個。

內容如下,語法就不解(jie)釋了,一看就知道(dao)。

tcp and host 你的遠程ip

5、選擇好剛添加(jia)的這(zhe)個過濾器,雙擊wifi這(zhe)個 interface 進入就開始(shi)捕獲(huo)了。

6、我用 telnet 連接這臺服務器的 6379 端口 telnet ip 6379,因為這臺服務器上裝著 redis,可以模擬發數據。

在(zai)控制臺中連接到 6379 端口(kou)成功,然后在(zai) Wireshark 上馬上捕獲到了。

這(zhe)就(jiu)是三次(ci)握手的過程。

7、然后直(zhi)接(jie)關掉終端,這樣會自動觸發斷(duan)開(kai)連接(jie),并(bing)且發送最(zui)少(shao)的數據,方便我們觀察。整個的過程都被 Wireshark 完(wan)整的捕(bu)捉(zhuo)到了。

第(di)一部(bu)分是(shi)連(lian)接(jie)建立的三次握手,第(di)二部(bu)分是(shi)發了長度為 1個字(zi)節(jie)的數據,第(di)三步是(shi)客戶端(duan)主動發起(qi)的斷(duan)開(kai)連(lian)接(jie)的四次揮(hui)手過程。

Wireshark 簡單介紹

有圖先看圖

概覽信息

也就是(shi)圖(tu)中(zhong)最上面的(de)紅色(se)框部分(fen)。這一次的(de)連接建立和中(zhong)斷(duan)一共產生(sheng)了(le)來回 8 次的(de)請求,每次請求會在列(lie)表(biao)上列(lie)出時間、源端(duan)IP、目(mu)的(de)端(duan)IP、以太網幀(zhen)長度以及(ji)概覽信(xin)息(xi),包括數據傳輸方向(源端(duan)口(kou)(kou)->目(mu)標端(duan)口(kou)(kou))、標記情況、序號(hao)、確認序號(hao)、窗口(kou)(kou)大小等等。

以太網幀

在每次請求信息中(zhong),還包括(kuo)以太網幀,因(yin)為信息最(zui)終都會通過(guo)幀的(de)形式發送出(chu)去。

IP數據報

還有 IP 數據(ju)報內容,其中包含了(le)源端(duan) IP 和 目的端(duan) IP 等信息(xi)。

TCP段

TCP 段當(dang)然是重點了,其中(zhong)包含了 TCP 協議中(zhong)的所有(you)信息(xi),包括端(duan)口(kou)號、

粘包、半包

MTU是什么

MTU 全稱是最大傳輸單元,一個在網絡上傳輸的包不能無限大,MTU 一般是對于鏈路層而言的,拿以太網來說,在鏈路層允許發送的最大的以太網幀的數據部分就是 1500字節。注意是以太網幀的數據部分,再加(jia)上以太網幀的頭部,會(hui)大于1500字節。

通過 ifconfig(windows 系統是(shi) ipconfig)可查看本機各個網絡接(jie)口(網卡)的MTU 大小。

MSS是什么

MSS 指TCP最大報文(wen)長(chang)度,是(shi)TCP協議定義的(de)一個選(xuan)項,MSS選(xuan)項用于(yu)在TCP連接建立時,收發(fa)雙方協商通信時每一個報文(wen)段所能(neng)承載的(de)最大數(shu)據長(chang)度。還是(shi)用以太網(wang)為例(li),MTU是(shi) 1500字(zi)節(jie),減(jian)去TCP頭(20字(zi)節(jie))和IP頭(20字(zi)節(jie)),就是(shi)MSS 1460字(zi)節(jie)。

粘包

粘包(bao)(bao)(bao)就是將幾(ji)個(ge)比較小的 TCP 包(bao)(bao)(bao)合并成一個(ge)包(bao)(bao)(bao),這樣就只發送(song)一次就可以將多個(ge)小包(bao)(bao)(bao)發送(song)出去。例如下面(mian)這樣,一個(ge)TCP報(bao)文(wen)請(qing)求中,包(bao)(bao)(bao)含小包(bao)(bao)(bao)A、B、C,每(mei)一個(ge)小包(bao)(bao)(bao)原本都是一個(ge)TCP報(bao)文(wen)。

為什么要粘包(bao)呢?一個一個發(fa)送(song)不行嗎?

其實是可以的(de),只不(bu)過(guo)在(zai)多數情況下(xia)來一(yi)(yi)個包(bao)馬上就(jiu)發送(song)可能會(hui)造成網絡擁塞(sai),一(yi)(yi)個TCP 報(bao)文傳輸(shu)(shu)到鏈路層的(de)時候,會(hui)加(jia)上TCP頭和(he)IP頭,占用(yong)40字(zi)節,如果發送(song)的(de)數據內容(rong)很小,比如只有(you)1個字(zi)節,為(wei)了(le)這一(yi)(yi)字(zi)節的(de)內容(rong),要(yao)有(you)40倍的(de)額外的(de)信息被傳輸(shu)(shu),是不(bu)是有(you)點浪費。

為了(le)減少這種浪費,TCP 協議就(jiu)做了(le)一些(xie)優化(hua),比如 Nagle 算法:

  • Nagle 算法規定每次只有收到上一個包的確認(ACK)之后,才會發送下一個包,在這個時間段內正好將小的包粘到一起;
  • 但是太多的包也不行,大小不能超過 MSS ,也就是前面剛說的 1460字節,太大了裝不下;
  • 如果沒有那么多小包,也不能一直等著,有一個超時時間,大約是200ms,超過這個時間也要發送;

由于現(xian)在的(de)(de)寬帶和設備性(xing)能(neng)的(de)(de)提升,Nagle 算法其(qi)(qi)實可(ke)以(yi)關(guan)閉(bi)了,有些設備上默(mo)認就(jiu)是關(guan)閉(bi)的(de)(de),也可(ke)以(yi)在寫 Socket 的(de)(de)代碼的(de)(de)時(shi)候主(zhu)動關(guan)閉(bi)掉,關(guan)閉(bi)之(zhi)后(hou)呢,只要(yao)接收端處理能(neng)力夠快(kuai),可(ke)以(yi)保(bao)證(zheng)來一個包馬上發送,對(dui)那(nei)些要(yao)求實時(shi)反饋的(de)(de)應(ying)用來說(shuo)尤其(qi)(qi)重要(yao)。

那來(lai)一(yi)(yi)個(ge)包發一(yi)(yi)個(ge)包,是(shi)不是(shi)就不會(hui)有(you)粘(zhan)包的(de)問題了?也不是(shi),這(zhe)就要(yao)看接(jie)收端(duan)(duan)的(de)處理(li)能力(li)了,接(jie)收端(duan)(duan)會(hui)有(you)一(yi)(yi)個(ge)接(jie)收緩沖區,來(lai)不及被應(ying)用(yong)程序處理(li)的(de)會(hui)暫時放到這(zhe)里,如果應(ying)用(yong)程序處理(li)能力(li)較差(cha),這(zhe)里還(huan)是(shi)會(hui)出現粘(zhan)包。

拆包

既然發生了粘包,就要把這些大包拆成小包。怎么拆分其實都是上層應用的事兒了,核心要點就是約定好分隔符。舉個簡單的例子,比如說將包A和包B用一個特殊字符 $分(fen)隔開,那應用在拆(chai)包的(de)時(shi)候(hou)就要根據這個特(te)殊(shu)字符進行分(fen)隔。當然了,真(zhen)實情況要比這個復雜的(de)多,如果你用過 Netty,就會(hui)發現 Netty 提供了多種處(chu)理粘包拆(chai)包的(de)方式。

什么是半包

粘包是為了將多個(ge)(ge)小(xiao)包變成(cheng)一個(ge)(ge)大(da)包,而半包是把(ba)超大(da)包拆成(cheng)小(xiao)包。比(bi)如(ru)下圖,假(jia)設包B是一個(ge)(ge)很大(da)的包,已經超過(guo)了MSS 了,單(dan)單(dan)發送它自己都發不過(guo)去了,所以只(zhi)能將它拆開(kai),一部分一部分的發送。

半包(bao)就沒那么復(fu)雜了,純粹是因為單獨(du)的包(bao)太(tai)大,協議不支持這么大的包(bao),只能拆開(kai)。

這樣一部(bu)分(fen)一部(bu)分(fen)的(de)包,到(dao)了接(jie)收端之后就要將其合并為(wei)一個(ge)整(zheng)體,合并也(ye)比較簡單(dan),就是如果這個(ge)部(bu)分(fen)包沒有開(kai)始或沒有結(jie)束標志,就表示它不是完整(zheng)的(de),需要給其找(zhao)到(dao)對應的(de)其他部(bu)分(fen)。

滑動窗口

接收方通告的窗口稱(cheng)為(wei)(wei) offered window,意(yi)思就(jiu)是說我(wo)這邊可以接受的最大字節數為(wei)(wei)這么多。例如下圖中的紅框部分為(wei)(wei) offered window, 大小為(wei)(wei) 6 字節,發送(song)(song)端最大一(yi)次只能(neng)發送(song)(song) 6 個(ge)字節,要(yao)不然接收方就(jiu)沒(mei)有能(neng)力接收了。

可用窗口 = offered window - 已經發(fa)送(song)但未(wei)被確認的(de)字節大(da)(da)小(xiao)(xiao),這個值(zhi)由發(fa)送(song)方(fang)(fang)自己計算。前面說(shuo)了三次(ci)握手,發(fa)送(song)方(fang)(fang)發(fa)出去(qu)包(bao),接(jie)收方(fang)(fang)接(jie)到后會反回(hui)一個 ACK,發(fa)出去(qu)但未(wei)收到ACK的(de)數據也會占(zhan)用窗口,表明接(jie)收方(fang)(fang)正(zheng)在處理,所以(yi),可用窗口的(de)大(da)(da)小(xiao)(xiao)是 offered window 減去(qu)未(wei)收到 ACK 的(de)大(da)(da)小(xiao)(xiao)。

為什么叫滑動(dong)窗(chuang)口呢,看(kan)上面的(de)圖(tu),把一(yi)個個字節想(xiang)象成(cheng)排成(cheng)一(yi)排的(de)格子(zi)。

首先看時刻1:紅色格(ge)子的部分(fen)就(jiu)(jiu)是(shi)(shi)offered window,大小為6字(zi)(zi)節,后(hou)面10、11、12字(zi)(zi)節因為沒在(zai)窗(chuang)口(kou)內,所(suo)以(yi)不能(neng)發送。已發送但未(wei)被(bei)確認(ren)的也占(zhan)用窗(chuang)口(kou)大小,所(suo)以(yi)最(zui)終可(ke)用窗(chuang)口(kou)就(jiu)(jiu)是(shi)(shi) 7、8、9這三個(ge)字(zi)(zi)節。

再看時刻2:剛才(cai)未被確認的 4、5、6字節(jie)收到(dao)了(le) ACK,所以(yi)1-6都(dou)變成(cheng)了(le)過去式(shi),然(ran)后窗(chuang)(chuang)口覆蓋到(dao)了(le)7、8、9、10、11、12 這(zhe)6個字節(jie),對比時刻(ke)1和時刻(ke)2,給我們(men)的感覺就是窗(chuang)(chuang)口(紅(hong)色格子(zi))向右滑動(dong)了(le),這(zhe)就是所謂(wei)的滑動(dong)窗(chuang)(chuang)口了(le)。

還有(you),窗口兩個邊沿的(de)相對運(yun)動增加(jia)或減少了窗口的(de)大小。

  • 當(dang)窗(chuang)口左邊沿向右邊沿靠近為窗(chuang)口合攏。這種現象(xiang)發生在(zai)數據(ju)(ju)被發送和確認時(shi),假設現在(zai)接(jie)收方(fang)(fang)處理數據(ju)(ju)的(de)(de)時(shi)間(jian)變長了,來不及快(kuai)速(su)處理,那接(jie)收方(fang)(fang)在(zai)下次(ci)ACK的(de)(de)時(shi)候返回的(de)(de)窗(chuang)口大小(xiao)可(ke)能(neng)就會變小(xiao)。

  • 當窗口右邊沿向右移動(dong)時(shi)將允(yun)許發送更多的(de)數據, 我們稱之為窗口張開。 這種現象發 生在另一端的(de)接收進程(cheng)讀取已(yi)經確認的(de)數據并釋放了 TCP的(de)接收緩存時(shi)。

慢啟動和擁塞避免算法

在使用 TCP 傳輸的過程中,肯定(ding)是(shi)希望(wang)數據傳送的越(yue)(yue)(yue)快越(yue)(yue)(yue)好,但是(shi)在實際使用場景中,由(you)(you)于發(fa)送端和接收端處理(li)數據的速度不一(yi)致,或者由(you)(you)于中間(jian)(jian)路(lu)由(you)(you)器(qi)(qi)性能(neng)(neng)限(xian)制(zhi)、帶寬限(xian)制(zhi)等原因,發(fa)送的速度越(yue)(yue)(yue)快,越(yue)(yue)(yue)有可(ke)能(neng)(neng)導致丟包的情況。比如一(yi)下子發(fa)送了10M的數據出(chu)來,但是(shi)中間(jian)(jian)路(lu)由(you)(you)器(qi)(qi)只(zhi)能(neng)(neng)處理(li) 5 M,很可(ke)能(neng)(neng)就會把一(yi)些(xie)包丟棄。

因而設計了(le)(le)慢啟動和擁塞避(bi)免(mian)算法,這兩(liang)個設計都是為了(le)(le)合理的(de)匹配發(fa)端的(de)發(fa)送速度與收(shou)端的(de)處理速度。

慢啟動

在連(lian)接(jie)剛建立的(de)(de)時候,發送端也不知道應(ying)該(gai)按什(shen)么速度發比(bi)較合(he)適,所(suo)以就(jiu)采用了一種漸進式的(de)(de)方式,就(jiu)是慢啟動(dong)的(de)(de)方式。

前面說了 offered window 是(shi)接(jie)收(shou)(shou)(shou)端的(de),在發送(song)端也(ye)有(you)一(yi)個窗口,叫(jiao)做擁塞(sai)窗口,記做 cwnd,擁塞(sai)窗口初始化為 1 ,表(biao)示 1個報(bao)文段,也(ye)就(jiu)(jiu)(jiu)是(shi)允許發送(song)1個報(bao)文段,之后每當每當收(shou)(shou)(shou)到接(jie)收(shou)(shou)(shou)端返(fan)回的(de) ACK 時(shi)(shi),就(jiu)(jiu)(jiu)將 cwnd 的(de)值加(jia)1。第一(yi)次(ci)發送(song)一(yi)個數(shu)(shu)據報(bao),當收(shou)(shou)(shou)到 ACK 后,cwnd 變(bian)為2,然后下一(yi)次(ci)發送(song)兩(liang)個數(shu)(shu)據報(bao),當收(shou)(shou)(shou)到這兩(liang)個數(shu)(shu)據報(bao)的(de) ACK 時(shi)(shi),cwnd 就(jiu)(jiu)(jiu)變(bian)成 4 。以此類推,這個增長是(shi)呈指數(shu)(shu)級的(de)。

但是(shi),在(zai)這(zhe)個(ge)(ge)過程中,也(ye)是(shi)有限制(zhi)的(de),發送(song)(song)的(de)數(shu)據(ju)報(bao)(bao)大(da)(da)小(xiao)要在(zai)消息接收端(duan)(duan)返回的(de)通告(gao)窗(chuang)口大(da)(da)小(xiao)和 cwnd 中取較小(xiao)的(de)那個(ge)(ge)值。假設一個(ge)(ge)報(bao)(bao)文大(da)(da)小(xiao)為 1024 字節,當 cwnd 為2,通告(gao)窗(chuang)口大(da)(da)小(xiao)為 4096 字節時,那發送(song)(song)端(duan)(duan)你可以(yi)連著發送(song)(song)2個(ge)(ge)數(shu)據(ju)報(bao)(bao),也(ye)就(jiu)是(shi)取 cwnd 的(de)值,當 cwnd 為8 時,通告(gao)窗(chuang)口大(da)(da)小(xiao)仍然為 4096 字節時,那發送(song)(song)端(duan)(duan)最多可連續發送(song)(song) 4 個(ge)(ge)數(shu)據(ju)報(bao)(bao),也(ye)就(jiu)是(shi)不(bu)能超過 4096 字節。

擁塞避免

擁塞避(bi)免算法其(qi)實和慢啟動(dong)是在(zai)一(yi)起使用(yong)的。在(zai)慢啟動(dong)中除了有擁塞窗口外, 還有一(yi)個叫做啟動(dong)門限(ssthresh)的參數。啟動(dong)門限默(mo)認的是 65535 字節。

在(zai)慢(man)啟動中,cwnd 是呈指數級增(zeng)(zeng)長,但(dan)是這個增(zeng)(zeng)長速(su)度(du)太快(kuai)了(le),所以,擁塞避(bi)免算法就是讓這個增(zeng)(zeng)速(su)減(jian)緩的方(fang)式。

當 cwnd < ssthresh 的時候,就(jiu)使用慢啟動。

當 cwnd > ssthresh 的時(shi)候,就(jiu)啟(qi)動擁塞避(bi)免算法。

擁(yong)塞避免算法保證當 cwnd 超過限制之后,每次收(shou)到一(yi)個確認時將 cwnd 增加 1/cwnd。

當擁(yong)塞發(fa)生時(shi)(shi)(超時(shi)(shi)或收(shou)到(dao)重(zhong)復確認),ssthresh 被(bei)設(she)置為當前窗口大小(xiao)的一半(cwnd和接收(shou)方通告窗口大小(xiao)的最小(xiao)值,但最少(shao)為 2個報文段)。

用一張圖來說明慢啟動和擁塞避免算法

假(jia)定(ding)(ding)當 cwnd 為32個(ge)報(bao)文段(duan)(duan)時(shi)(shi)就(jiu)會發生擁塞。于是(shi)設置 ssthresh 為1 6個(ge)報(bao)文段(duan)(duan), 而 cwnd 為1個(ge)報(bao)文段(duan)(duan)。 在(zai)時(shi)(shi)刻(ke) 0發送了一(yi)個(ge)報(bao)文段(duan)(duan), 并假(jia)定(ding)(ding)在(zai)時(shi)(shi)刻(ke) 1接收到它的 ACK,此時(shi)(shi) cwnd 增加為2。接著發送了2個(ge)報(bao)文段(duan)(duan),并假(jia)定(ding)(ding)在(zai)時(shi)(shi)刻(ke) 2接收到它們的 ACK,于是(shi) cwnd 增加為4 (對每(mei)個(ge) ACK 增加1次)。這(zhe)種指(zhi)數增加算法(fa)一(yi)直進(jin)行到在(zai)時(shi)(shi)刻(ke) 3和4之間收到8個(ge)A C K后 cwnd 等(deng) 于 ssthresh 時(shi)(shi)才停(ting)止,從(cong)該時(shi)(shi)刻(ke)起,cwnd 以線(xian)性方(fang)式增加,在(zai)每(mei)個(ge)往返(fan)時(shi)(shi)間內最(zui)多增加 1個(ge)報(bao) 文段(duan)(duan)。

正如我們在這(zhe)個圖中看到的(de)(de)那樣, 術語“慢(man)啟動”并不完全正確。 它只(zhi)是采用了比引起 擁塞更慢(man)些的(de)(de)分組傳(chuan)輸速(su)率(lv), 但在慢(man)啟動期間進入(ru)網(wang)絡的(de)(de)分組數增加(jia)的(de)(de)速(su)率(lv)仍然是在增加(jia)的(de)(de)。 只(zhi)有在達到 ssthresh 擁塞避免算法起作用時,這(zhe)種增加(jia)的(de)(de)速(su)率(lv)才會慢(man)下來。

重傳機制

什(shen)么情(qing)況(kuang)下要重傳(chuan),當發送端認為丟包了就要重傳(chuan),有兩(liang)種情(qing)況(kuang)下發送端就認為丟包了,于是就會發起重傳(chuan)。

超時重傳

發(fa)(fa)送端在(zai)一段時(shi)間(jian)(jian)(超(chao)時(shi)時(shi)間(jian)(jian))后沒有(you)收到發(fa)(fa)送端返回的(de)(de) ACK ,就認(ren)為這個包(bao)丟了,這個超(chao)時(shi)時(shi)間(jian)(jian)并(bing)不(bu)是(shi)固定的(de)(de)。

這里面有兩個概念,RTT 和 RTO。

  • RTT(Round Trip Time):往(wang)返時(shi)延,也就是(shi)數據包從發出去(qu)到收到對(dui)應 ACK 的時(shi)間。RTT 是(shi)針對(dui)連接的,每一(yi)個連接都有各自獨立的 RTT。

  • RTO(Retransmission Time Out):重傳超時,也就(jiu)是前面說的(de)超時時間。

快速重傳

接收(shou)端回復的 ACK 會帶(dai)著包的序號(hao),當接收(shou)端重復三次(ci)收(shou)到同一個序號(hao)的ACK時,就要重傳這個包;

比如下面圖中畫的這樣:

1、seq=1的包發過去(qu),接收端(duan)ACK=2,表(biao)示(shi)期望(wang)下(xia)次(ci)出現的序號為(wei)2,然后發送端(duan)就(jiu)發了 seq=2的包,接收端(duan)接到(dao)(dao)(dao)后回復 ACK=3,表(biao)示(shi)期望(wang)下(xia)次(ci)收到(dao)(dao)(dao)序號為(wei)3的包,這是發送端(duan)第一次(ci)收到(dao)(dao)(dao) ACK=3;

2、發(fa)送端繼(ji)續發(fa)送 seq=3 的(de)(de)包,但是(shi)這(zhe)個包可(ke)能傳輸(shu)的(de)(de)比(bi)較(jiao)慢(比(bi)如路由選擇的(de)(de)不好),接收端一(yi)直沒收到;

3、發(fa)送(song)端先不管,繼(ji)續發(fa)送(song) seq=4 的包(bao),接收(shou)端收(shou)到(dao)后,回(hui)復ACK,正常情況下(xia)應該是 ACK=5,但是序號為3的包(bao)還(huan)沒收(shou)到(dao),所以再次(ci)回(hui)復ACK=3,這是第(di)二次(ci)收(shou)到(dao)ACK=3;

4、發送(song)端(duan)繼續(xu)不管,接著發送(song) seq=5的包,接收(shou)端(duan)收(shou)到(dao)后,回復(fu)ACK,正常情況下(xia)應該(gai)是(shi) ACK=6,但是(shi)序號(hao)為3的包還沒收(shou)到(dao),所以再(zai)次回復(fu)ACK=3,這是(shi)第三次收(shou)到(dao)ACK=3;

到目前為止(zhi),已(yi)經收(shou)到三(san)次(ci) ACK=3了(le),然后發送端就(jiu)重(zhong)新發送 seq=3的(de)包,這(zhe)時(shi)候就(jiu)當做這(zhe)個包已(yi)經丟(diu)了(le)。這(zhe)就(jiu)是快速重(zhong)傳。


如果覺得還不錯的話,給個推薦吧!

公眾號「古時(shi)的風箏」,Java 開發者,專(zhuan)注 Java 及周邊生(sheng)態(tai)。堅(jian)持原創干貨輸出,你(ni)可選擇現在就(jiu)關注我,或(huo)者看看歷史(shi)文章再(zai)關注也(ye)不遲。長按二(er)維碼關注,跟(gen)我一(yi)起(qi)變優(you)秀!

posted @ 2023-03-24 09:49  風的姿態  閱讀(1584)  評論(0)    收藏  舉報