【計(jì)算機(jī)網(wǎng)絡(luò) 1】TCP 基礎(chǔ)知識
前言
提到 TCP,許多人都會(huì)感到晦澀難懂。今天,就以一種直白的方式,講講 TCP 的基本內(nèi)容。 馬上要過年了,也不聊太復(fù)雜的知識,說些簡單的。 以下內(nèi)容均為原創(chuàng),并且純靠作者腦子記,所以可能有錯(cuò)誤,歡迎指正!(大家也盡量背下來 :D) 概述
TCP,全稱 Transmission Control Protocol,傳輸控制協(xié)議,位于傳輸層。TCP 是一種
面向連接的、可靠的、基于字節(jié)流的
協(xié)議。 把這些特點(diǎn)拆開分析,
面向連接
:在使用 TCP 傳輸數(shù)據(jù)之前,必須使用 Syn 數(shù)據(jù)包建立連接;而在數(shù)據(jù)傳輸完成后,必須使用 Fin 包斷開連接?!斑B接”在物理層面并不存在,雙方狀態(tài)均為 Establish 時(shí),連接已經(jīng)產(chǎn)生。
可靠
:在連接的任意一方傳輸數(shù)據(jù)后,另一方收到數(shù)據(jù),此時(shí)接收方必須回復(fù) Ack 包以確認(rèn)報(bào)文收到。如果發(fā)送方判斷(猜測)該報(bào)文未被收到,則會(huì)重傳報(bào)文。
基于字節(jié)流
:沒啥好說的,發(fā)送方和接收方都可以通過 Stream 讀取或?qū)懭霐?shù)據(jù);字節(jié)流可以想象成一條河流,不過里面流的是“數(shù)據(jù)”,任意一方向內(nèi)寫數(shù)據(jù),操作系統(tǒng)便會(huì)發(fā)送數(shù)據(jù),而操作系統(tǒng)讀取到數(shù)據(jù),又會(huì)轉(zhuǎn)化為字節(jié)流形式,讓接收方讀取。 報(bào)文頭部格式
TCP 報(bào)文頭部中包含以下幾個(gè)字段(僅列舉重要內(nèi)容),
序列號
:該報(bào)文的起始位置,建立連接時(shí)初始化。這也意味著 TCP 的報(bào)文順序可以打亂。
確認(rèn)應(yīng)答號
:下一次“希望收到的”報(bào)文序列號。例如,收到 1 2 3 字節(jié)的數(shù)據(jù)后,確認(rèn)應(yīng)答號為 4;收到 1 3 4 7 字節(jié)的數(shù)據(jù)后,確認(rèn)應(yīng)答號為 2(因?yàn)樽止?jié) 2 還未收到)。
Syn
:表示希望建立連接。
Fin
:表示希望斷開連接。
Ack
:表示“報(bào)文已收到”。
Rst
:表示連接出現(xiàn)問題,需要立刻斷開。這將會(huì)立刻設(shè)置發(fā)送方與接收方狀態(tài)為 Close(正常情況下,主動(dòng)關(guān)閉連接方還需等待 2RTT 的時(shí)間,避免第四次揮手的 Ack 丟包)。 歷史遺留的處理
簡單來說,歷史遺留就是以前的 TCP 連接被網(wǎng)絡(luò)延遲的報(bào)文。 例如,曾經(jīng)有一個(gè) Syn 114 的報(bào)文,后由于種種原因取消了該連接,換了另一個(gè)連接,Syn 值為 514,此時(shí) Syn 114 先到達(dá)服務(wù)端,但是客戶端已經(jīng)“忘記了” Syn 114,于是發(fā)現(xiàn)服務(wù)端的確認(rèn)應(yīng)答號不匹配,直接 Rst 干掉了連接;隨后 Syn 514 抵達(dá)服務(wù)端,按照正常步驟三次握手即可。 超時(shí)重傳
網(wǎng)絡(luò)環(huán)境錯(cuò)綜復(fù)雜,難免遇到數(shù)據(jù)包丟失情況。因此,TCP 設(shè)計(jì)了重傳方式,其中最簡單粗暴的就是超時(shí)重傳。 TCP 在數(shù)據(jù)包長時(shí)間未收到 Ack 時(shí),會(huì)自動(dòng)重傳,而這個(gè)時(shí)間限制稱為 RTO。 RTO 計(jì)算方式在此不多贅述,簡單來說就是 RTO 略大于 RTT(報(bào)文往返一次的時(shí)間稱為 RTT)。RTO 的值隨著網(wǎng)絡(luò)環(huán)境變化不斷浮動(dòng)。 而且,如果重傳的報(bào)文再次超時(shí),RTO 值會(huì)加倍。到達(dá)一定程度后,便會(huì)直接關(guān)閉連接,而且不使用 Fin 或 Rst。 快速重傳
超時(shí)重傳雖然也能保證報(bào)文交付,但是總有個(gè)超時(shí)時(shí)間,用戶體驗(yàn)一般。 因此產(chǎn)生了快速重傳,舉個(gè)栗子: 客戶端發(fā)送 Seq 1 2 3 4 5,而 Seq 2 丟包,此時(shí)服務(wù)端收到 1 3 4 5。由于缺少 Seq 2,所以服務(wù)端 Ack 均回 2。 客戶端收到連續(xù)的 Ack 2,認(rèn)為 Seq 2 丟包,則會(huì)進(jìn)行重傳,此時(shí)服務(wù)端回 Ack 6。 不過,就上面的例子,客戶端能否判斷,僅僅是 Seq 2 丟包,還是 Seq 2 3 4 5 丟包?顯然不行。于是便產(chǎn)生了 SACK。 SACK 會(huì)在 Ack 報(bào)文中附帶接收方緩存的地圖。例如,收到了 1 3 4 5,便會(huì)帶上 SACK 3-5,說明 3 4 5 均收到,而 2 未收到。 還有更進(jìn)一步的 D-SACK,能夠讓雙方清楚,是數(shù)據(jù)丟失,還是 Ack 丟失,還是被網(wǎng)絡(luò)延遲。 總結(jié)
本期內(nèi)容真的超級簡單……更難的滑動(dòng)窗口、流量控制、擁塞控制,都在后面呢…… 好了,1500 字了,先水到這里吧。