面向連接的傳輸:TCP
TCP:概述
點(diǎn)對(duì)點(diǎn)
- 一個(gè)發(fā)送方、一個(gè)接收方
可靠的、按順序的字節(jié)流
- 沒(méi)有報(bào)文邊界
管道化(流水線)
- TCP擁塞控制和流量控制設(shè)置窗口大小
發(fā)送和接收緩存
全雙工數(shù)據(jù)
- 在同一連接中數(shù)據(jù)流雙向流動(dòng)
- MSS:最大報(bào)文段大小
面向連接
- 在數(shù)據(jù)交換之前,通過(guò)握手(交換控制報(bào)文)初始化發(fā)送方、接收方的狀態(tài)變量
有流量控制
- 發(fā)送方不會(huì)淹沒(méi)接收方
TCP報(bào)文段結(jié)構(gòu)
TCP序號(hào),確認(rèn)號(hào)
序號(hào)
- 報(bào)文段首字節(jié)的在字節(jié)流的編號(hào)
確認(rèn)號(hào)
- 期望從另一方收到的下一個(gè)字節(jié)的序號(hào)
- 累計(jì)確認(rèn)
接收方如何處理亂序的報(bào)文段-沒(méi)有規(guī)定
TCP往返延時(shí)(RTT)和超時(shí)
怎樣設(shè)置TCP超時(shí)
- 比RTT要長(zhǎng)
- 但RTT是變化的
- 太短:太早超時(shí)
- 不必要的重傳
- 太長(zhǎng):對(duì)報(bào)文段丟失反應(yīng)太慢,消極
怎樣估計(jì)RTT
-
SampleRTT:測(cè)量從報(bào)文段發(fā)出到收到確認(rèn)的時(shí)間
- 如果有重傳,忽略此次測(cè)量
-
SampleRTT會(huì)變化,因此估計(jì)的RTT應(yīng)該比較平滑
- 對(duì)幾個(gè)最近的測(cè)量值求平均,而不是僅用當(dāng)前的SampleRTT
TCP序號(hào)和確認(rèn)號(hào)
TCP往返延時(shí)和超時(shí)
E s t i m a t e d R T T = ( 1 ? a ) ? E s t i m a t e d R T T + a ? S a m p l e R T T EstimatedRTT = (1- a)*EstimatedRTT + a*SampleRTT EstimatedRTT=(1?a)?EstimatedRTT+a?SampleRTT
- 指數(shù)加權(quán)移動(dòng)平均
- 過(guò)去樣本的影響呈指數(shù)衰減
- 推薦值: a = 0.125 a = 0.125 a=0.125
設(shè)置超時(shí)
-
E
s
t
i
m
t
e
d
R
T
T
EstimtedRTT
EstimtedRTT + 安全邊界時(shí)間
- E s t i m a t e d R T T EstimatedRTT EstimatedRTT變化大(方差大) → 較大的安全邊界時(shí)間
-
S
a
m
p
l
e
R
T
T
SampleRTT
SampleRTT會(huì)偏離
E
s
t
i
m
a
t
e
d
R
T
T
EstimatedRTT
EstimatedRTT多遠(yuǎn):
- D e v R T T = ( 1 ? β ) ? D e v R T T + β ? ∣ S a m p l e R T T ? E s t i m a t e d R T T ∣ DevRTT = (1-β)*DevRTT + β*|SampleRTT-EstimatedRTT| DevRTT=(1?β)?DevRTT+β?∣SampleRTT?EstimatedRTT∣
- 推薦值: β = 0.25 β = 0.25 β=0.25
超時(shí)時(shí)間間隔設(shè)置為:
- T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 ? D e v R T T TimeoutInterval = EstimatedRTT + 4*DevRTT TimeoutInterval=EstimatedRTT+4?DevRTT
TCP:可靠數(shù)據(jù)傳輸
- TCP在IP不可靠服務(wù)的基礎(chǔ)上建立了rdt
- 管道化的報(bào)文段
- GBN or SR
- 累計(jì)確認(rèn)
- 單個(gè)重傳定時(shí)器
- 是否可以接受亂序的,沒(méi)有規(guī)范
- 管道化的報(bào)文段
- 通過(guò)以下事件觸發(fā)重傳
- 超時(shí)(只重發(fā)那個(gè)最早的未確認(rèn)段:SR)
- 重復(fù)的確認(rèn)
- 首先考慮簡(jiǎn)化的TCP發(fā)送方:
- 忽略重復(fù)的確認(rèn)
- 忽略流量控制和擁塞控制
TCP發(fā)送方(簡(jiǎn)化版)
TCP發(fā)送方事件
<font color=red從應(yīng)用層接收數(shù)據(jù):
- 用nextseq創(chuàng)建報(bào)文段
- 序號(hào)nextseq為報(bào)文段首字節(jié)的字節(jié)流編號(hào)
- 如果還沒(méi)有運(yùn)行,啟動(dòng)定時(shí)器
- 定時(shí)器與最早未確認(rèn)的報(bào)文段關(guān)聯(lián)(單個(gè)重傳定時(shí)器)
- 過(guò)期間隔:TimeOutInterval
超時(shí):
- 重傳后沿最老的報(bào)文段
- 重新啟動(dòng)定時(shí)器
收到確認(rèn):
- 如果是對(duì)尚未確認(rèn)的報(bào)文段確認(rèn)
- 更新已被確認(rèn)的報(bào)文序號(hào)(后沿移動(dòng))
- 如果當(dāng)前還有未被確認(rèn)的報(bào)文段,重新啟動(dòng)定時(shí)器 (發(fā)完,就關(guān)掉定時(shí)器)
偽代碼
上述操作的偽代碼
// 初始化
NextSeqNum = InitialSeqNum
SendBase = InitialSeqNum
// 一直循環(huán)
loop (forever) {
// 判斷事件
switch(event)
// 如果收到了應(yīng)用層的數(shù)據(jù)
event: data received from application above
// 用NextSeqNum創(chuàng)建TCPsegment
create TCP segment with sequence number NextSeqNum
// 如果定時(shí)器不在運(yùn)行的話,開(kāi)始
if (timer currently not running)
start timer
// 傳給IP
pass segment to IP
// 前沿移動(dòng)
NextSeqNum = NextSeqNum + length(data)
event: timer timeout
retransmit not-yet-acknowledged segment with
smallest sequence number
start timer
event: ACK received, with ACK field value of y
if (y > SendBase) {
SendBase = y
if (there are currently not-yet-acknowledged segments)
start timer
}
} /* end of loop forever */
注釋:
- SendBase-1: 最后一個(gè)累積確認(rèn)的字節(jié)
- 例:
- SendBase-1 = 71;y= 73, 因此接收方期望73+ ; y是ACK的值
- y > SendBase,因此新的數(shù)據(jù)被確認(rèn)
TCP:重傳
接收方產(chǎn)生TCP ACK的建議
接收方的事件 | TCP接收方動(dòng)作 | 補(bǔ)充 |
---|---|---|
所期望序號(hào)的報(bào)文段按序到達(dá)。所有在期望序號(hào)之前的數(shù)據(jù)都已經(jīng)被確認(rèn) | 延遲發(fā)送ACK(提高效率,少發(fā)一個(gè)ACK)。對(duì)另一個(gè)按序報(bào)文段的到達(dá)最多等待500ms。如果下一個(gè)報(bào)文段在這個(gè)時(shí)間間隔內(nèi)沒(méi)有到達(dá),則發(fā)送一個(gè)ACK。 | 就是當(dāng)接受到y(tǒng)0之后,不發(fā)送ACK=y0+1,而是當(dāng)順序接受到y(tǒng)1之后,發(fā)送ACK=y1+1注意必須是順序接受到,如果是亂序,仍然請(qǐng)求y0+1,如果超時(shí)還未接受到,再發(fā)y0+1 |
有期望序號(hào)的報(bào)文段到達(dá)。 另一個(gè)按序報(bào)文段等待發(fā)送ACK | 立即發(fā)送單個(gè)累積ACK,以確認(rèn)兩個(gè)按序報(bào)文段。 | 就是上一條說(shuō)的情況 |
比期望序號(hào)大的報(bào)文段亂序到達(dá)。 檢測(cè)出數(shù)據(jù)流中的間隔 | 立即發(fā)送重復(fù)的ACK,指明下一個(gè)期待字節(jié)的序號(hào) | 如果收到了y0,然后亂序收到了y2,那么重新請(qǐng)求ACK=y0 + 1 |
能部分或完全填充接收數(shù)據(jù)間隔 的報(bào)文段到達(dá) | 若該報(bào)文段起始于間隔(gap)的低端,則立即發(fā)送ACK(給確認(rèn)。反映下一段的需求)。 | 請(qǐng)求ACK=y0+1,此時(shí)已經(jīng)亂序收到了y2的內(nèi)容請(qǐng)求之后得到的gap并不能填充y0到y(tǒng)2的空間,只能達(dá)到y(tǒng)1,因此重新請(qǐng)求ACK=y1 + 1 |
快速重傳
- 超時(shí)周期往往太長(zhǎng)
- 在重傳丟失報(bào)文段之前的延時(shí)太長(zhǎng)
- 通過(guò)<font color=red重復(fù)的ACK來(lái)檢測(cè) 報(bào)文段丟失
- 發(fā)送方通常連續(xù)發(fā)送大量 報(bào)文段
- 如果報(bào)文段丟失,通常會(huì)引起多個(gè)重復(fù)的ACK
- 如果發(fā)送方收到同一數(shù)據(jù) 的3個(gè)冗余ACK,重傳最 小序號(hào)的段:
- 快速重傳:在定時(shí)器過(guò)時(shí)之前重發(fā)報(bào)文段
- 它假設(shè)跟在被確認(rèn)的數(shù)據(jù) 后面的數(shù)據(jù)丟失了
- 第一個(gè)ACK是正常的;(比如第一個(gè)ACK=50,表明收到了49,是正常的,請(qǐng)求50)
- 收到第二個(gè)該段的ACK,表 示接收方收到一個(gè)該段后的亂序段; (因?yàn)樵俅握?qǐng)求50)
- 收到第3,4個(gè)該段的ack,表 示接收方收到該段之后的2個(gè) ,3個(gè)亂序段,可能性非常大段丟失了
快速重傳算法
event: ACK received, with ACK field value of y
if (y > SendBase) {
SendBase = y
if (there are currently not-yet-acknowledged segments)
start timer
}
else { // 已確認(rèn)報(bào)文段的一個(gè)重復(fù)確認(rèn)
increment count of dup ACKs received for y
if (count of dup ACKs received for y = 3) {
resend segment with sequence number y // 快速重傳
}
TCP 流量控制
接收方控制發(fā)送方,不讓發(fā)送方發(fā)送的太多、太快以至于讓 接收方的緩沖區(qū)溢出
- 接收方在其向發(fā)送方的TCP段 頭部的rwnd字段“通告”其空閑buffer大小
- RcvBuffer大小通過(guò)socket選項(xiàng)設(shè)置 (典型默認(rèn)大小為4096 字節(jié))
- 很多操作系統(tǒng)自動(dòng)調(diào)整 RcvBuffer
- 發(fā)送方限制未確認(rèn)(“inflight”)字節(jié)的個(gè)數(shù)≤接收 方發(fā)送過(guò)來(lái)的 rwnd 值
- 保證接收方不會(huì)被淹沒(méi)
TCP連接管理
在正式交換數(shù)據(jù)之前,發(fā)送方和接收方握手建立通信關(guān)系:
- 同意建立連接(每一方都知道對(duì)方愿意建立連接)
- 同意連接參數(shù)
同意建立連接
在網(wǎng)絡(luò)中,2次握手建 立連接總是可行嗎?
- 變化的延遲(連接請(qǐng)求的段沒(méi)有丟,但可能超時(shí))
- 由于丟失造成的重傳 (e.g. req_conn(x))
- 報(bào)文亂序
- 相互看不到對(duì)方
以下是兩次握手的問(wèn)題:
- 半連接
- 接受老數(shù)據(jù)問(wèn)題
三次握手
三次握手解決:半連接和接收老數(shù)據(jù)問(wèn)題
TCP三次握手 FSM
TCP關(guān)閉連接
- 客戶端,服務(wù)器分別關(guān)閉它自己這一側(cè)的連接
- 發(fā)送FIN bit = 1的TCP段
- 一旦接收到FIN,用ACK回應(yīng)
- 接到FIN段,ACK可以和它自己發(fā)出的FIN段一起發(fā) 送
- 可以處理同時(shí)的FIN交換
接收老數(shù)據(jù)問(wèn)題
[外鏈圖片轉(zhuǎn)存中…(img-IY4eQv16-1708397928036)]
TCP三次握手 FSM
[外鏈圖片轉(zhuǎn)存中…(img-JuahJ8RB-1708397928036)]文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-834276.html
TCP關(guān)閉連接
- 客戶端,服務(wù)器分別關(guān)閉它自己這一側(cè)的連接
- 發(fā)送FIN bit = 1的TCP段
- 一旦接收到FIN,用ACK回應(yīng)
- 接到FIN段,ACK可以和它自己發(fā)出的FIN段一起發(fā) 送
- 可以處理同時(shí)的FIN交換
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-834276.html
到了這里,關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)——20面向連接的傳輸:TCP的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!