摘要:傳輸控制協(xié)議概述最主要的特點是面向連接的運輸層協(xié)議。應用程序在使用協(xié)議之前,必須先建立連接。當時,表明此報文段的發(fā)送發(fā)的數(shù)據(jù)已發(fā)送完畢,并要求釋放運輸連接窗口占字節(jié)。
傳輸控制協(xié)議 TCP 概述 TCP 最主要的特點
TCP 是面向連接的運輸層協(xié)議。應用程序在使用 TCP 協(xié)議之前,必須先建立 TCP 連接。在傳送數(shù)據(jù)完畢后,必須釋放已經(jīng)建立的 TCP 連接
每一條 TCP 連接只能有兩個端點,每一條 TCP 連接只能是點對點的(一對一)
TCP 提供可靠交付的服務。通過 TCP 連接傳送的數(shù)據(jù),無差錯、不丟失、不重復,并且按序到達
TCP 提供全雙工通信。TCP 允許通信雙方的應用進程在任何時候都能發(fā)送數(shù)據(jù)。TCP 連接的兩端都設有發(fā)送緩存和接受緩存,用來臨時存放雙向通信的數(shù)據(jù)
面向字節(jié)流。TCP 中的“流”指的是流入到進程或從進程流出的字節(jié)序列
面向字節(jié)流“面向字節(jié)流”的含義是:雖然應用程序和 TCP 的交互式一次一個數(shù)據(jù)塊(大小不等),但 TCP 把應用程序交下來的數(shù)據(jù)僅僅看成是一連串的無結(jié)構(gòu)的字節(jié)流。TCP 并不知道所傳送的字節(jié)流的含義
TCP 不保證接收方應用程序所收到的數(shù)據(jù)塊和發(fā)送方應用程序所發(fā)出的數(shù)據(jù)塊具有對應大小的關系
例如,發(fā)送方應用程序交給發(fā)送方的 TCP 共10個數(shù)據(jù)塊,但接收方的 TCP 可能只用了4個數(shù)據(jù)塊就把收到的字節(jié)流交付上層的應用程序
接收方應用程序收到的字節(jié)流必須和發(fā)送方應用程序發(fā)出的字節(jié)流完全一樣。接收方的應用程序必須有能力識別收到的字節(jié)流,把它還原成有意義的應用層數(shù)據(jù)
TCP 和 UDP 在發(fā)送報文時采用的方式完全不同。TCP 并不關心應用進程一次把多長的報文發(fā)送到 TCP 的緩存中,而是根據(jù)對方給出的窗口值和當前網(wǎng)絡擁塞的程度來決定一個報文段應包含多少個字節(jié)(UDP 發(fā)送的報文長度是應用進程給出的)。如果應用進程傳送到 TCP 緩存的數(shù)據(jù)塊太長,TCP 就可以把它劃分短一些再傳送。如果應用進程一次只發(fā)來一個字節(jié),TCP 也可以等待積累有足夠多的字節(jié)后再構(gòu)成報文段發(fā)送出去
《PHP面試問答》 https://github.com/colinlet/P...TCP 的連接
結(jié)合實際 PHP 面試,系統(tǒng)的匯總面試中的各種各樣的問題,嘗試提供簡潔準確的答案。如果你在 PHP 面試中遇到問題,歡迎提 Issues 交流。包含網(wǎng)絡協(xié)議、數(shù)據(jù)結(jié)構(gòu)與算法、PHP、Web、MySQL、Redis、Linux、安全、設計模式、架構(gòu)、自我介紹、離職原因、職業(yè)規(guī)劃、準備問題等部分
如果覺得不錯歡迎 star 關注,正在不斷持續(xù)更新中~~
TCP 把連接作為最基本的抽象。TCP 的許多特性都與 TCP 是面向連接的這個基本特性有關
TCP 連接的端點叫做套接字(socket)或插口,根據(jù) RFC 793 的定義:端口號拼接到(concatenated with) IP 地址即構(gòu)成了套接字
套接字 socket = (IP 地址:端口號)
每一條 TCP 連接唯一地被通信兩端的兩個端點(即兩個套接字)所確定
TCP 連接 ::= {socket1, socket2} = {(IP1: port1), (IP2: port2)}
TCP 連接就是由協(xié)議軟件所提供的一種抽象。TCP 連接的端口是個很抽象的套接字,即( IP地址: 端口號)。同一個 IP 地址可以有多個不同的 TCP 連接,而同一個端口號也可以出現(xiàn)在多個不同的 TCP 連接中
易混淆的 socket同一個名詞 socket 卻可表示多種不同的意思,以下 socket 的意思跟本文中所引用的 RFC 793 定義的 socket(指端口號拼接到 IP 地址)不同
允許應用程序訪問連網(wǎng)協(xié)議的應用編程接口 API(Application Programming Interface),即運輸層和應用層之間的接口,稱為 socket API,并簡稱為 socket
在 socket API 中使用的一個函數(shù)名也叫做 socket
調(diào)用 socket 函數(shù)的端點稱為 socket,如“創(chuàng)建一個數(shù)據(jù)報 socket”
調(diào)用 socket 函數(shù)時,其返回值稱為 socket 描述符,可簡稱為 socket
在操作系統(tǒng)內(nèi)核中連網(wǎng)協(xié)議的 Berkeley 實現(xiàn),稱為 socket 實現(xiàn)
可靠傳輸?shù)墓ぷ髟?/b> 理想的傳輸條件理想的傳輸條件有以下兩個特點
傳輸信道不產(chǎn)生差錯
不管發(fā)送方以多快的速度發(fā)送數(shù)據(jù),接收方總是來得及處理收到的數(shù)據(jù)
實際的網(wǎng)絡不具備以上兩個理想條件。需要使用一些可靠的傳輸協(xié)議,當出現(xiàn)差錯時讓發(fā)送方重傳出現(xiàn)差錯的數(shù)據(jù),同時在接收方來不及處理收到的數(shù)據(jù)時,及時告訴發(fā)送方適當減低發(fā)送數(shù)據(jù)的速度。這樣,不可靠的傳輸信道就能夠?qū)崿F(xiàn)可靠傳輸了
停止等待協(xié)議全雙工通信的雙方既是發(fā)送方也是接收方。把傳送的數(shù)據(jù)單元都稱為分組?!巴V沟却本褪敲堪l(fā)完一個分組就停止發(fā)送,等待對方的確認。在收到確認后再發(fā)送下一個分組
無差錯情況 出現(xiàn)差錯只要超過一段時間沒有收到確認,就認為剛才發(fā)送的分組丟失了,因而重傳前面發(fā)送過的分組。這就叫做超時重傳。要實現(xiàn)超時重傳,就要在每發(fā)送完一個分組時設置一個超時計時器
發(fā)送完一個分組后,必須暫時保留已發(fā)送的分組的副本(在發(fā)生超時重傳時使用)。只有在收到相應的確認后才能清除暫時保留的分組副本
分組和確認分組都必須進行編號。這樣才能明確是哪一個發(fā)送出去的分組收到了確認,而哪一個分組還沒有收到確認
超時計時器的重傳時間應當比數(shù)據(jù)在分組傳輸?shù)钠骄禃r間更長一些
確認丟失和確認遲到使用上述的確認和重傳機制,我們就可以在不可靠的傳輸網(wǎng)絡上實現(xiàn)可靠的通信
像上述的這種可靠傳輸協(xié)議常稱為自動重傳請求 ARQ(Automatic Repeat reQuest)。重傳的請求是自動進行的。接收方不需要請求發(fā)送方重傳某個出錯的分組
信道利用率停止等待協(xié)議的優(yōu)點是簡單,但缺點是信道利用率太低
為了提高傳輸效率,發(fā)送方可以不使用低效率的停止等待協(xié)議,而是采用流水線傳輸。流水線傳輸就是發(fā)送方可連續(xù)發(fā)送多個分組,不必每發(fā)完一個分組就停頓下來等待對方的確認。這樣可使信道上一直有數(shù)據(jù)不間斷地在傳送。這種傳輸方式可以獲得很高的信道利用率
連續(xù) ARQ 協(xié)議位于發(fā)送窗口內(nèi)的5個分組都可以連續(xù)發(fā)送出去,而不需要等待對方的確認??梢蕴岣咝诺览寐?/p>
接收方一般都是采用累積確認的方式。接收方不需要對收到的分組逐個發(fā)送確認,而是在收到幾個分組后,對按序到達的最后一個分組發(fā)送確認
積累確認有優(yōu)點也有缺點。優(yōu)點是:容易實現(xiàn),即使確認丟失也不必重傳。缺點是不能向發(fā)送方反映出接收方已經(jīng)正確收到的所有分組的信息
TCP 報文段的首部格式TCP 雖然是面向字節(jié)流的,但 TCP 傳送的數(shù)據(jù)單元卻是報文段。一個 TCP 報文段分為首部和數(shù)據(jù)兩部分。TCP 報文段首部的前20個字節(jié)是固定的,后面有4n字節(jié)是根據(jù)需要而增加的選項(n是整數(shù))。因此 TCP 首部的最小長度是20字節(jié)
首部字段源端口和目的端口 各占2個字節(jié),分別寫入源端口號和目的端口號
序號 占4字節(jié)。序號范圍是[0, 232-1],共232(即4 294 967 296)個序號。序號增加到232-1后,下一個序號就又回到0。在一個 TCP 連接中傳送的字節(jié)流中的每一個字節(jié)都按順序編號
確認號 占4字節(jié),是期望收到對方下一個報文段的第一個數(shù)據(jù)字節(jié)的序號
數(shù)據(jù)偏移 占4字節(jié),它指出 TCP 報文段的數(shù)據(jù)起始處距離 TCP 報文段的起始處有多遠。這個字段實際上是指出 TCP 報文段的首部長度
保留 占6位,保留為今后使用,但目前應置為0
下面有6個控制位,用來說明本報文段的性質(zhì)
緊急 URG(URGent) 當 URG=1 時,表明緊急指針字段有效。它告訴系統(tǒng)此報文段中有緊急數(shù)據(jù),應盡快傳送(相當于高優(yōu)先級的數(shù)據(jù)),而不是按原先的排隊順序來傳送
確認 ACK(ACKnowledgment) 僅當 ACK=1 時確認號字段才有效。當 ACK=0 時,確認號無效。TCP 規(guī)定,在連接建立后所有傳送的報文段都必須把 ACK 置1
推送 PSH(Push) 當兩個應用進程進行交互式的通信時,有時在一端的應用進程希望在鍵入一個命令后立即就能夠收到對方的響應
復位 RST(ReSeT) 當 RST=1 時,表明 TCP 連接中出現(xiàn)嚴重差錯(如由于主機崩潰或其他原因),必須釋放連接,然后再重新建立運輸連接
同步 SYN(SYNnchronization) 在連接建立時用來同步序號。當 SYN=1 而 ACK=0 時,表明這是一個連接請求報文段。對方若同意建立連接,則應在響應的報文段中使 SYN=1 和 ACK=1
終止 FIN(FINis) 用來釋放一個連接。當 FIN=1 時,表明此報文段的發(fā)送發(fā)的數(shù)據(jù)已發(fā)送完畢,并要求釋放運輸連接
窗口 占2字節(jié)。窗口值是[0, 216-1]之間的整數(shù)。窗口值作為接收方讓發(fā)送方設置其發(fā)送窗口的依舊
檢驗和 占2字節(jié)。檢驗和字段檢驗的范圍包括首部和數(shù)據(jù)這兩部分
緊急指針 占2字節(jié)。緊急指針僅在 URG=1 時才有意義,它指出本報文段中的緊急數(shù)據(jù)的字節(jié)數(shù)
選項 長度可變,最長可達40字節(jié)
TCP 可靠傳輸?shù)膶崿F(xiàn) 以字節(jié)為單位的滑動窗口 發(fā)送窗口構(gòu)造TCP 的滑動窗口是以字節(jié)為單位的。假定 A 收到了 B 發(fā)來的確認報文段,其中窗口是20字節(jié),而確認號是31(這表明 B 期望收到的下一個序號是31,而序號30為止的數(shù)據(jù)已經(jīng)收到了)。根據(jù)這兩個數(shù)據(jù),A 就構(gòu)造出自己的發(fā)送窗口
發(fā)送窗口標識:在沒有收到 B 的確認的情況下,A 可以連續(xù)把窗口內(nèi)的數(shù)據(jù)都發(fā)送出去。凡是已經(jīng)發(fā)送出去的數(shù)據(jù),在未收到確認之前都必須暫時保留,以便在超時重傳時使用
發(fā)送窗口變化發(fā)送窗口的位置由窗口前沿和后沿的位置共同確定。發(fā)送窗口后沿的變化情況有兩種,即不動(沒有收到新的確認)和前移(收到了新的確認)。發(fā)送窗口后沿不可能向后移動,因為不能撤銷已收到的確認
發(fā)送窗口前沿通常是不斷向前移動,但也有可能不動。這對應于兩種情況:
一是沒有收到信的確認,對應通知的窗口大小也不變
二是收到了新的窗口單對方通知的窗口縮小了,使得發(fā)送窗口前沿正好不動
發(fā)送窗口前沿也有可能向后收縮。這發(fā)生在對方通知的窗口縮小了。但 TCP 的標準強烈不贊成這樣做。因為很可能發(fā)送方在收到這個通知以前已經(jīng)發(fā)生了窗口中的許多數(shù)據(jù),現(xiàn)在又要收縮窗口,不讓發(fā)送這些數(shù)據(jù),這樣就會產(chǎn)生一些錯誤
要描述一個發(fā)送窗口的狀態(tài)需要三個指針:P1,P2,P3。指針都指向字節(jié)的序號。這三個指針指向的幾個部分的意義如下:
小于 P1 的是已發(fā)送并已收到確認的部分,而大于 P3 的是不允許發(fā)送的部分
P3 - P1 = A 的發(fā)送窗口
P2 - P1 已發(fā)送但尚未收到確認的字節(jié)數(shù)
P3 - P2 允許發(fā)送但當前尚未發(fā)送的字節(jié)數(shù)(又稱為可用窗口或有效窗口)
B 的接收窗口大小是20。在接收窗口外面,到30號為止的數(shù)據(jù)是已經(jīng)發(fā)送過確認,并且已經(jīng)交付主機了。因此在 B 可以不再保留這些數(shù)據(jù)。接收窗口內(nèi)的序號(31~50)是允許接收的。在上圖中,B 收到了序號為32和33的數(shù)據(jù)。這些數(shù)據(jù)沒有按序到達,因為序號為31的數(shù)據(jù)沒有收到(也許丟失了,也許滯留在網(wǎng)絡中的某處)。請注意,B 只能對按序收到的數(shù)據(jù)中的最高序號給出確認,因此 B 發(fā)送的確認報文段中的確認號仍然是31(即期望收到的序號),而不是32或33
現(xiàn)在假定 B 收到了序號為31的數(shù)據(jù),并把序號為31~33的數(shù)據(jù)交付主機,然后 B 刪除這些數(shù)據(jù)。接著把接收窗口向前移動3個序號,同時給 A 發(fā)送確認,其中窗口值仍為20,但確認號是34.這表明 B 已經(jīng)收到了到序號33為止的數(shù)據(jù)。B 還收到了序號為37,38和40的數(shù)據(jù),但這些都沒有按序到達,只能先暫存在接收窗口中。A 收到 B 的確認后,就可以把發(fā)送窗口向前滑動3個序號,但指針 P2 不動?,F(xiàn)在 A 的可用窗口增大了,可發(fā)送的序號范圍是42~53
A 在繼續(xù)發(fā)送完序號42~53的數(shù)據(jù)后,指針 P2 向前移動和 P3 重合。發(fā)送窗口內(nèi)的序號都已用完,但還沒有再收到確認。由于 A 的發(fā)送窗口已滿,可用窗口已減小到零,因此必須停止發(fā)送。發(fā)送窗口內(nèi)所有的數(shù)據(jù)都已正確到達 B,B 也早已發(fā)出了確認。但所有這些確認都滯留在網(wǎng)絡中。在沒有收到 B 的確認時,A 不能猜測:“或許 B 收到了吧!”為了保證可靠傳輸,A 只能認為 B 還沒有收到這些數(shù)據(jù)。于是,A 在經(jīng)過一段時間后(由超時計時器控制)就重傳這部分數(shù)據(jù),重新設置超時計時器,知道收到 B 的確認為止。如果 A 收到確認號落在發(fā)送窗口內(nèi),那么 A 就可以發(fā)送窗口繼續(xù)向前滑動,并發(fā)送新的數(shù)據(jù)
緩存和窗口發(fā)送方維持的發(fā)送緩存和發(fā)送窗口,以及接收方維持的接收緩存和接收窗口
發(fā)送緩存用來暫時存放:
發(fā)送應用程序傳送給對方 TCP 準備發(fā)送的數(shù)據(jù)
TCP 已發(fā)送出但尚未收到確認的數(shù)據(jù)
已被確認的數(shù)據(jù)應當從發(fā)送緩存中刪除,因此發(fā)送緩存和發(fā)送窗口的后沿是重合的。發(fā)送應用程序必須控制寫入緩存的速率,不能太快,否則發(fā)送緩存就會沒有存放數(shù)據(jù)的空間
接收緩存用來暫時存放:
按序到達的、但尚未被接收應用程序讀取的數(shù)據(jù)
未按序到達的數(shù)據(jù)
收到的分組被檢測出有差錯,則丟棄。接收應用程序來不及讀取收到的數(shù)據(jù),接收緩存最終就會被填滿,使接收窗口減小到零。接收應用程序能夠及時從接收緩存中讀取收到的數(shù)據(jù),接收窗口就可以增大,最大亦不能超過接收緩存的大小
要點小結(jié):
雖然 A 的發(fā)送窗口是根據(jù) B 的接收窗口設置的,但在同一時刻,A 的發(fā)送窗口并不總是和 B 的接收窗口一樣大。通過網(wǎng)絡傳送窗口值需要經(jīng)歷一定的時間滯后,該時間并不確定的
對于不按序到達的數(shù)據(jù),TCP 通常是先臨時存放在接收窗口,等字節(jié)流中所缺少的字節(jié)收到后,在按序交付上層的應用進程
TCP 要求接收方必須有累積確認的功能,這樣可以減少傳輸開銷
超時重傳時間的選擇TCP 的發(fā)送方在規(guī)定的時間內(nèi)沒有收到確認就要重傳已發(fā)送的報文段。這種重傳的概念是很簡單的,但重傳時間的選擇卻是 TCP 最復雜的問題之一
由于 TCP 的下層是互聯(lián)網(wǎng)環(huán)境,發(fā)送的報文段可能只經(jīng)過一個高速率的局域網(wǎng),也可能經(jīng)過多個低速率的網(wǎng)絡,并且每個 IP 數(shù)據(jù)報所選擇的路由還可能不同。如果把超時重傳時間設置得太短,就會引起很多報文段的必須要的重傳,使網(wǎng)絡負荷增大。但若把超時重傳時間設置的過長,則又使網(wǎng)絡的空閑時間增大,減低了傳輸效率
TCP 采用了一種自適應算法,它記錄一個報文段發(fā)出的時間,以及收到相應的確認的時間。這兩個時間之差就是報文段的往返時間 RTT
新的 RTTs = (1 - α) x (舊的 RTTs) + α x (新的 RTT 樣本)
RTT:報文段往返時間
RTTs:加權平均往返時間
α: 0 ≤ α < 1,RFC 6298 推薦的 α 值為 1/8,即 0.125
RTO = RTTs + 4 x RTTD
RTO:超時重傳時間
RTTD:RTT 的偏差的加權平均值
新的 RTTD = (1 - β) x (舊的 RTTD) + β x |RTTs - 新的 RTT 樣本|
β:小于1的系數(shù),推薦值是 1/4,即 0.25
TCP 流量控制 利用滑動窗口實現(xiàn)流量控制流量控制(flow control):讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收
利用滑動窗口機制可以很方便地在 TCP 連接上實現(xiàn)對發(fā)送方的流量控制
發(fā)送方的發(fā)送窗口不能超過接收方給出的接收窗口的數(shù)值。TCP 的窗口單位是字節(jié),不是報文段
避免死鎖:TCP 為每一個連接設有一個持續(xù)計時器(persistence timer)。只要 TCP 連接的一方收到對方的零窗口通知,就啟動持續(xù)計時器。若持續(xù)計時器設置的時間到期,就發(fā)送一個零窗口探測報文段(僅攜帶1字節(jié)的數(shù)據(jù)),而對方就在確認這個探測報文段時給出了現(xiàn)在的窗口值。如果窗口仍是零,那么收到這個報文段的一方就重新設置持續(xù)計時器。如果窗口不是零,那么死鎖的僵局就可以打破了
TCP 的傳輸效率 發(fā)送機制TCP 維持一個變量,它等于最大報文段長度 MSS。只要緩存中存放的數(shù)據(jù)達到 MSS 字節(jié)時,就組裝成一個 TCP 報文段發(fā)送出去
由發(fā)送方的應用進程指明要求發(fā)送報文段,即 TCP 支持的推送(push)操作
發(fā)送方的一個計時器期限到了,這時把當前已有的緩存數(shù)據(jù)裝入報文段(但長度不能超過 MSS)發(fā)送出去
Nagle 算法在 TCP 的實現(xiàn)中廣泛使用 Nagle 算法
若發(fā)送應用進程把要發(fā)送的數(shù)據(jù)逐個字節(jié)地送到 TCP 的發(fā)送緩存,則發(fā)送方就把第一個數(shù)據(jù)字節(jié)先發(fā)送出去,把后面到達的數(shù)據(jù)字節(jié)都緩存起來。當發(fā)送方收到對第一個數(shù)據(jù)字符的確認后,再把發(fā)送緩存中的所有數(shù)據(jù)組裝成一個報文段發(fā)送出去,同時繼續(xù)對隨后到達的數(shù)據(jù)進行緩存。只有在收到對前一個報文段的確認后才繼續(xù)發(fā)送下一個報文段。當數(shù)據(jù)達到較快而網(wǎng)絡速率較慢時,用這樣的方法可明顯地減少所用的網(wǎng)絡寬帶。Nagle 算法還規(guī)定,當?shù)竭_的數(shù)據(jù)已達到發(fā)送窗口大小的一半或已達到報文段的最大長度時,就立即發(fā)送一個報文段。這樣可以有效提高網(wǎng)絡的吞吐量
糊涂窗口綜合征TCP 接收方的緩存已滿,僅剩一個字節(jié),并還將保持這種狀態(tài)持續(xù)一段時間。導致發(fā)送方只能發(fā)送一個字節(jié)。導致網(wǎng)絡的效率很低
為了解決這個問題,可以讓接收方等待一段時間,使得或者接受緩存已有足夠空間容納一個最長的報文段,或者等到接受緩存已有一半空閑的空間。只要出現(xiàn)這兩種情況之一,接收方就發(fā)出確認報文,并向發(fā)送方通知當前的窗口大小。發(fā)送方也不要發(fā)送大小的報文段,而是把數(shù)據(jù)積累成足夠大的報文段,或達到接收方緩存的空間的一半大小
TCP 的擁塞控制 擁塞控制的一般原理在計算機網(wǎng)絡中的鏈路容量(即寬帶)、交換結(jié)點中的緩存和處理機等,都是網(wǎng)絡資源。在某段時間,若對網(wǎng)絡中某一資源的需求超過了該資源所能提供的可用部分,網(wǎng)絡的性能就要變壞。這種情況就叫做擁塞(congestion)
擁塞控制就是防止過多的數(shù)據(jù)注入到網(wǎng)絡中,這樣可以使網(wǎng)絡中的路由器或鏈路不致過載。擁塞控制所要做的都是一個前提,就是網(wǎng)絡能夠承受現(xiàn)有的網(wǎng)絡負荷
TCP 的擁塞控制方法TCP 進行擁塞控制的算法有四種,即慢開始(slow-start)、擁塞避免(congestion avoidance)、快重傳(fast retransmit)和快恢復(fast recovery)
慢開始當主機開始發(fā)送數(shù)據(jù)時,由于并不清楚網(wǎng)絡的負荷情況,如果立即把大量數(shù)據(jù)字節(jié)注入到網(wǎng)絡,就有可能引起網(wǎng)絡發(fā)生擁塞。經(jīng)驗證明,較好的方法是先探測一下,即由小到大逐漸增大發(fā)送窗口,也就是說,由小到大逐漸增大擁塞窗口數(shù)值
cwnd:發(fā)送方的擁塞窗口,開始發(fā)送方設置 cwnd = 1
擁塞避免讓擁塞窗口 cwnd 緩慢地增大,即每經(jīng)過一個往返時間 RTT 就把發(fā)送方的擁塞窗口 cwnd 加1,而不是像慢開始階段那樣加倍增加。因此在擁塞避免階段就有“加法增大” AI(Additive Increase)的特點。這表明在擁塞避免階段,擁塞窗口 cwnd 按線性規(guī)律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多
“擁塞避免”并非完全能夠避免擁塞,而是把擁塞窗口控制為按線性規(guī)律增長,使網(wǎng)絡比較不容易出現(xiàn)擁塞
在執(zhí)行慢開始算法時,發(fā)送方每收到一個隊新報文段的確認 ACK,就把擁塞窗口值加1,然后開始下一輪的傳輸。因此擁塞窗口 cwnd 隨著傳輸輪次按指數(shù)規(guī)律增長。當擁塞窗口 cwnd 增長到慢開始門限值 ssthresh 時,就改成執(zhí)行擁塞避免算法,擁塞窗口按線性規(guī)律增長
ssthresh:慢開始門限,一般的,會有一個初始值,下圖中為16個報文段
當擁塞窗口 cwnd = 24 時,網(wǎng)絡出現(xiàn)了超時,發(fā)送方判斷為網(wǎng)絡擁塞。于是調(diào)整門限值 ssthresh = cwnd / 2 = 12,同時設置擁塞窗口 cwnd = 1,進入慢開始階段
快重傳采用快重傳算法可以讓發(fā)送方盡早知道發(fā)生了個別報文段的丟失??熘貍魉惴ㄊ紫纫蠼邮辗讲灰却约喊l(fā)送數(shù)據(jù)時才進行捎帶確認,而是要立即發(fā)送確認,即使收到了失序的報文段也要立即發(fā)出對已收到的報文段的重復確認
快恢復發(fā)送發(fā)知道當前只是丟失了個別的報文段。于是不啟動慢開始,而是執(zhí)行快恢復算法。這時,發(fā)送方調(diào)整門限值 ssthresh = cwnd / 2 = 8,同時設置擁塞窗口 cwnd = ssthresh = 8,并開始執(zhí)行擁塞避免算法
TCP Reno 版本:區(qū)別于老的 TCP Tahao 版本
TCP 的運輸連接管理TCP 是面向連接的協(xié)議。運輸連接是用來傳送 TCP 報文的。TCP 運輸連接的建立和釋放是每一次面向連接的通信中必不可少的過程。運輸連接有三個階段,連接建立、數(shù)據(jù)傳送和連接釋放。運輸?shù)倪B接管理就是使運輸連接的建立和釋放都能夠正常地進行
在 TCP 連接建立過程中要解決以下三個問題:
要使每一方能夠確知對方的存在
要允許雙方協(xié)商一些參數(shù)(最大窗口值、是否使用窗口擴大選項和時間戳選項以及服務質(zhì)量等)
能夠?qū)\輸實體資源(緩存大小、連接表中的項目等)進行分配
TCP 的連接建立TCP 建立連接的過程叫做握手,握手需要在客戶和服務器之間交換三個 TCP 報文段
連接建立過程最初客戶/服務器的 TCP 進程都處于 CLOSED(關閉)狀態(tài)。在本實例中,A 主動打開連接,而 B 被動打開連接
B 的 TCP 服務器進程先創(chuàng)建傳輸控制塊 TCB,并處于 LISTEN(收聽) 狀態(tài),等待客戶的連接請求
A 的 TCP 客戶進程創(chuàng)建傳輸控制模塊 TCB。并向 B 發(fā)出連接請求報文段,首部中的同部位 SYN = 1,選擇一個初始序號 seq = x。TCP 客戶端進程進入 SYN-SENT(同步已發(fā)送) 狀態(tài)。TCP 規(guī)定,SYN 報文段(即 SYN = 1 的報文段)不能攜帶數(shù)據(jù),但要消耗一個序號
B 收到連接請求報文段后,如同意建立連接,則向 A 發(fā)送確認。在確認報文段中應把 SYN 位和 ACK 位都置1,確認號是 ack = x + 1,同時也為自己選擇一個初始序號 seq = y。這時 TCP 服務器進程進入 SYN-RCVD(同步收到) 狀態(tài)。這個報文段也不能攜帶數(shù)據(jù),但同樣要消耗掉一個序號
TCP 客戶進程收到 B 的確認后,還要向 B 給出確認。確認報文段的 ACK 置1,確認號 ack = y + 1,而自己的序號 seq = x + 1。TCP 的標準規(guī)定,ACK 報文段可以攜帶數(shù)據(jù)。但如果不攜帶數(shù)據(jù)則不消耗序號,在這種情況下,下一個數(shù)據(jù)報文段的序號仍是 seq = x + 1。這時,TCP 連接已經(jīng)建立,A 進入 ESTABLISHED(已建立連接) 狀態(tài)
當 B 收到 A 的確認后,也進入 ESTABLISHED 狀態(tài)
傳輸控制塊 TCB(Transmission Control Block)存儲了每一個連接中的一些重要信息,如:TCP 連接表,指向發(fā)送和接收緩存的指針,指向重傳隊列的指針,當前的發(fā)送和接收序號等等四報文握手
B 發(fā)送給 A 的報文段,可拆成兩個報文段。先發(fā)送一個確認報文段(ACK = 1,ack = x + 1),然后再發(fā)送一個同步報文段(SYN = 1,seq = y)。這樣的過程就變成了四報文握手,與三報文握手效果一致
異常情況為什么 A 最后還要發(fā)送一次確認呢?這主要是為了防止已失效的連接請求報文段突然又傳到了 B,因而產(chǎn)生錯誤
正常情況:A 發(fā)出連接請求,但因連接請求報文丟失而未收到確認。于是 A 再重傳一次連接請求。后來收到了確認,建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接。A 共發(fā)送了兩個連接請求報文段,其中第一個丟失,第二個到達了 B,沒有“已失效的連接請求報文段”
異常情況:A 發(fā)出的第一個連接請求報文段并沒有丟失,而是在某些網(wǎng)絡結(jié)點長時間滯留了,以致延誤到連接釋放以后的某個時間才到達 B。本來這是一個早已失效的報文段。但 B 收到此失效的連接請求報文段后,就誤認為是 A 又發(fā)出一次新的連接請求。于是就向 A 發(fā)出確認報文段,同意建立連接。假定不采用報文握手,那么只要 B 發(fā)出確認,新的連接就建立了。
現(xiàn)在 A 并沒有發(fā)出建立連接的請求,因此不會理睬 B 的確認,也不會向 B 發(fā)送數(shù)據(jù)。但 B 卻以為新的運輸連接已經(jīng)建立了,并一直等待 A 發(fā)來數(shù)據(jù)。B 的許多資源就這樣被浪費了。TCP 的連接釋放 連接釋放過程采用三報文握手的辦法,可以防止上述現(xiàn)象的發(fā)生
A 的應用進程先向其 TCP 發(fā)出連接釋放報文段,并停止再發(fā)送數(shù)據(jù),主動關閉 TCP 連接。A 把連接釋放報文段首部的終止控制位 FIN 置1,其序號 seq = u,它等于前面已傳送過的數(shù)據(jù)的最后一個字節(jié)的序號加1。這時 A 進入 FIN-WAIT-1(終止等待1) 狀態(tài),等待 B 的確認。TCP 規(guī)定,F(xiàn)IN 報文段即使不攜帶數(shù)據(jù),也消耗一個序號
B 收到連接釋放報文段后即發(fā)出確認,確認號是 ack = u + 1,而這個報文段自己的序號是 v,等于 B 前面已傳送過的數(shù)據(jù)的最后一個字節(jié)的序號加1。B隨即進入 CLOSE-WAIT(關閉等待) 狀態(tài)。TCP 服務器進程這時應通知高層應用進程,因而從 A 到 B 這個方向的連接就釋放了,這時的 TCP 連接處于 半關閉(half-close) 狀態(tài),即 A 已經(jīng)沒有數(shù)據(jù)要發(fā)送了,但 B 若發(fā)送數(shù)據(jù),A 仍要接收。也就是說,從 B 到 A 這個方向的連接并未關閉,這個狀態(tài)可能會持續(xù)一段時間
A 收到來自 B 的確認后,就進入 FIN-WAIT-2(終止等待2) 狀態(tài),等待 B 發(fā)出的連接釋放報文段
若 B 已經(jīng)沒有要向 A 發(fā)送的數(shù)據(jù),其應用進程就通知 TCP 釋放連接。這時 B 發(fā)出的連接釋放報文段必須使 FIN = 1?,F(xiàn)假定 B 的序號為 w(在半關閉狀態(tài) B 可能又發(fā)送了一些數(shù)據(jù))。B 還必須重復上次已發(fā)送過的確認號 ack = u + 1。這時 B 就進入 LAST-ACK(最后確認)狀態(tài),等待 A 的確認
A 在收到 B 的連接釋放報文段后,必須對此發(fā)出確認。在確認報文段中把 ACK 置1,確認號 ack = w + 1,而自己的序號是 seq = u + 1(根據(jù) TCP 標準,前面發(fā)送過的 FIN 報文段要消耗一個序號)。然后進入到 TIME-WAIT(時間等待)狀態(tài)。此時 TCP 連接還沒有釋放掉。必須經(jīng)過時間等待計時器(TIME-WAIT timer)設置的時間2MSL后,A 才進入到 CLOSED 狀態(tài)
當 A 撤銷相應的傳輸控制塊 TCB 后,就結(jié)束了這次的 TCP 連接
時間 MSL 叫做最長報文段壽命(Maximum Segment Lifetime),RFC 793建議設為2分鐘。但這完全是從工程上來考慮的,對于現(xiàn)在的網(wǎng)絡,MSL = 2分鐘可能太長了一些TIME-WAIT 等待時間
為什么 A 在 TIME-WAIT 狀態(tài)必須等待 2MSL 的時間呢?
為了保證 A 發(fā)送的最后一個 ACK 報文段能夠到達 B。這個 ACK 報文段有可能丟失,因而使處在 LAST-ACK 狀態(tài)的 B 收不到對已發(fā)送的 FIN + ACK 報文段的確認。B 會超時 重傳這個 FIN + ACK 報文段,而 A 就能在 2MSL 時間內(nèi)收到這個重傳的 FIN + ACK 報文段。接著 A 重傳一次確認,重新啟動 2MSL 計時器。最后,A 和 B 都正常進入到 CLOSED 狀態(tài)。如果 A 在 TIME-WAIT 狀態(tài)不等待一段時間,而是在發(fā)完 ACK 報文段后立即釋放連接,那么就無法收到 B 重傳的 FIN + ACK 報文段,因而也不會再發(fā)送一次確認報文段。這樣,B 就無法安裝正常步驟進入 CLOSED 狀態(tài)
防止前面提到的“已失效的連接請求報文段”出現(xiàn)在本連接中。A 在發(fā)送完最后一個 ACK 報文段后,再經(jīng)過時間 2MSL,就可以使本連接持續(xù)的時間內(nèi)所產(chǎn)生的所有報文段都從網(wǎng)絡中消失。這樣就可以使下一個新的連接中不會出現(xiàn)這種舊的連接請求報文段
B 只要收到 A 發(fā)出的確認,就進入 CLOSED 狀態(tài)。同樣,B 在撤銷相應的傳輸控制 TCB 后,就結(jié)束了這次的 TCP 連接。B 結(jié)束 TCP 連接的時間要比 A 早一些
?;钣嫊r器(keepalive timer):服務器每收到一次客戶的數(shù)據(jù),就重新設置?;钣嫊r器,時間的設置通常是兩小時。若兩小時沒有收到客戶的數(shù)據(jù),服務器就發(fā)送一個探測報文段,以后則每隔75秒發(fā)送一次。若一連發(fā)送10個探測報文段后仍無客戶的響應,服務器就認為客戶端出了故障,接著就關閉這個連接
TCP 的有限狀態(tài)機為了更清晰地看出 TCP 連接的各種狀態(tài)之間的關系,下圖為 TCP 的有限狀態(tài)機。圖中每一個方框即 TCP 可能具有的狀態(tài)。每個方框中的大寫英文字符串是 TCP 標準所使用的 TCP 連接狀態(tài)名。狀態(tài)之間的箭頭表示可能發(fā)生的狀態(tài)變遷。箭頭旁邊的字,表明引起這種變遷的原因,或表明發(fā)生狀態(tài)變遷后又出現(xiàn)什么動作。請注意圖中有三種不同的箭頭。粗實線箭頭表示對客戶進程的正常變遷。粗虛線箭頭表示對服務器進程的正常變遷。另一種細線箭頭表示異常變遷
《TCP協(xié)議詳解》原文鏈接:https://blog.maplemark.cn/2019/04/tcp協(xié)議詳解.html?utm=sf
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/31362.html
摘要:協(xié)議地址解析協(xié)議,根據(jù)地址獲取地址。確認表示確認號字段有效,確認號無效。終止表示發(fā)送數(shù)據(jù)已發(fā)送完畢,要求釋放連接。 TCP/IP協(xié)議蔟分為4層結(jié)構(gòu),分別是應用層、傳輸層、網(wǎng)絡層和數(shù)據(jù)鏈路層,每一層都由特定的協(xié)議與對方進行通信,在進行數(shù)據(jù)通信時,發(fā)送端的數(shù)據(jù)從應用層往數(shù)據(jù)鏈路層方向流動,接收端的數(shù)據(jù)從數(shù)據(jù)鏈路層往應用層流動。 數(shù)據(jù)鏈路層 數(shù)據(jù)鏈路層的主要工作是對電信號進行分組并形成具有特...
摘要:面向消息的簡單文本協(xié)議。為提供了備選方案。但無論哪種場景,對于實際應用來說,這種通信形式層級過低。協(xié)議,來為瀏覽器和間的通信增加適當?shù)南⒄Z義。協(xié)議解決了瀏覽器發(fā)起請求以及服務器響應請求的細節(jié),假設協(xié)議并不存在,只能使用套接字來編寫應用。 最近有項目需求要用到websocket,剛開始以為很簡單,但是隨著遇到問題,深入了解,才知道websocket并不是想象中的那么簡單,這篇文章主要是...
摘要:面向消息的簡單文本協(xié)議。為提供了備選方案。但無論哪種場景,對于實際應用來說,這種通信形式層級過低。協(xié)議,來為瀏覽器和間的通信增加適當?shù)南⒄Z義。協(xié)議解決了瀏覽器發(fā)起請求以及服務器響應請求的細節(jié),假設協(xié)議并不存在,只能使用套接字來編寫應用。 最近有項目需求要用到websocket,剛開始以為很簡單,但是隨著遇到問題,深入了解,才知道websocket并不是想象中的那么簡單,這篇文章主要是...
閱讀 1411·2021-10-11 11:12
閱讀 3244·2021-09-30 09:46
閱讀 1633·2021-07-28 00:14
閱讀 3132·2019-08-30 13:49
閱讀 2581·2019-08-29 11:27
閱讀 3211·2019-08-26 11:52
閱讀 598·2019-08-23 18:14
閱讀 3435·2019-08-23 16:27