圖解TCP/IP協(xié)議
本文通過圖來梳理TCP-IP協(xié)議相關(guān)知識。TCP通信過程包括三個步驟:建立TCP連接通道,傳輸數(shù)據(jù),斷開TCP連接通道。如圖1所示,給出了TCP通信過程的示意圖。

圖1主要包括三部分:建立連接、傳輸數(shù)據(jù)、斷開連接。
1)建立TCP連接很簡單,通過三次握手便可建立連接。
2)建立好連接后,開始傳輸數(shù)據(jù)。TCP數(shù)據(jù)傳輸牽涉到的概念很多:超時重傳、快速重傳、流量控制、擁塞控制等等。
3)斷開連接的過程也很簡單,通過四次握手完成斷開連接的過程。
三次握手建立連接
三次握手建立連接的首要目的是確保傳輸?shù)目煽啃?,這也是TCP和UDP的關(guān)鍵區(qū)別。而確保可靠性的手段就是建立握手,其中用到了同步序列號。只有同步了序列號才有可靠的傳輸,TCP協(xié)議的許多特性都是依賴序列號實現(xiàn)的,比如流量控制、消息丟失后的重發(fā)等等,這也是三次握手中的報文被稱為SYN(Synchronize Sequence Numbers)。
第一次握手:客戶端發(fā)送syn包(seq=x)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);
第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=x+1),同時自己也發(fā)送一個SYN包(seq=y),即SYN+ACK包,此時服務(wù)器進(jìn)入SYN_RECV狀態(tài);
第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=y+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手。
握手過程中傳送的包里不包含數(shù)據(jù),三次握手完畢后,客戶端與服務(wù)器才正式開始傳送數(shù)據(jù)。理想狀態(tài)下,TCP連接一旦建立,在通信雙方中的任何一方主動關(guān)閉連接之前,TCP 連接都將被一直保持下去。
傳輸數(shù)據(jù)
a.超時重傳
超時重傳機(jī)制用來保證TCP傳輸?shù)目煽啃?。每次發(fā)送數(shù)據(jù)包時,發(fā)送的數(shù)據(jù)報都有seq號,接收端收到數(shù)據(jù)后,會回復(fù)ack進(jìn)行確認(rèn),表示某一seq號數(shù)據(jù)已經(jīng)收到。發(fā)送方在發(fā)送了某個seq包后,等待一段時間,如果沒有收到對應(yīng)的ack回復(fù),就會認(rèn)為報文丟失,會重傳這個數(shù)據(jù)包。
b.快速重傳
接受數(shù)據(jù)一方發(fā)現(xiàn)有數(shù)據(jù)包丟掉了。就會發(fā)送ack報文告訴發(fā)送端重傳丟失的報文。如果發(fā)送端連續(xù)收到標(biāo)號相同的ack包,則會觸發(fā)客戶端的快速重傳。比較超時重傳和快速重傳,可以發(fā)現(xiàn)超時重傳是發(fā)送端在傻等超時,然后觸發(fā)重傳;而快速重傳則是接收端主動告訴發(fā)送端數(shù)據(jù)沒收到,然后觸發(fā)發(fā)送端重傳。
c.流量控制
這里主要說TCP滑動窗流量控制。TCP頭里有一個字段叫Window,又叫Advertised-Window,這個字段是接收端告訴發(fā)送端自己還有多少緩沖區(qū)可以接收數(shù)據(jù)。于是發(fā)送端就可以根據(jù)這個接收端的處理能力來發(fā)送數(shù)據(jù),而不會導(dǎo)致接收端處理不過來。 滑動窗可以是提高TCP傳輸效率的一種機(jī)制。
d.擁塞控制
滑動窗用來做流量控制。流量控制只關(guān)注發(fā)送端和接受端自身的狀況,而沒有考慮整個網(wǎng)絡(luò)的通信情況。擁塞控制,則是基于整個網(wǎng)絡(luò)來考慮的??紤]一下這樣的場景:某一時刻網(wǎng)絡(luò)上的延時突然增加,那么,TCP對這個事做出的應(yīng)對只有重傳數(shù)據(jù),但是,重傳會導(dǎo)致網(wǎng)絡(luò)的負(fù)擔(dān)更重,于是會導(dǎo)致更大的延遲以及更多的丟包,于是,這個情況就會進(jìn)入惡性循環(huán)被不斷地放大。試想一下,如果一個網(wǎng)絡(luò)內(nèi)有成千上萬的TCP連接都這么行事,那么馬上就會形成“網(wǎng)絡(luò)風(fēng)暴”,TCP這個協(xié)議就會拖垮整個網(wǎng)絡(luò)。為此,TCP引入了擁塞控制策略。擁塞策略算法主要包括:慢啟動,擁塞避免,擁塞發(fā)生,快速恢復(fù)。
四次握手?jǐn)嚅_連接
第一次揮手:主動關(guān)閉方發(fā)送一個FIN,用來關(guān)閉主動方到被動關(guān)閉方的數(shù)據(jù)傳送,也就是主動關(guān)閉方告訴被動關(guān)閉方:我已經(jīng)不會再給你發(fā)數(shù)據(jù)了(當(dāng)然,在fin包之前發(fā)送出去的數(shù)據(jù),如果沒有收到對應(yīng)的ack確認(rèn)報文,主動關(guān)閉方依然會重發(fā)這些數(shù)據(jù)),但此時主動關(guān)閉方還可以接受數(shù)據(jù)。
第二次揮手:被動關(guān)閉方收到FIN包后,發(fā)送一個ACK給對方,確認(rèn)序號為收到序號+1(與SYN相同,一個FIN占用一個序號)。
第三次揮手:被動關(guān)閉方發(fā)送一個FIN,用來關(guān)閉被動關(guān)閉方到主動關(guān)閉方的數(shù)據(jù)傳送,也就是告訴主動關(guān)閉方,我的數(shù)據(jù)也發(fā)送完了,不會再給你發(fā)數(shù)據(jù)了。
第四次揮手:主動關(guān)閉方收到FIN后,發(fā)送一個ACK給被動關(guān)閉方,確認(rèn)序號為收到序號+1,至此,完成四次揮手。
如果您是開發(fā)者,或者對本篇文章感興趣,請關(guān)注本人,后續(xù)會更新更多相關(guān)文章!敬請期待!