1 TCP三次握手、四次揮手
2 TCP滑動窗口機制
image.png
- 客戶端不斷快速發(fā)送數(shù)據(jù)尖昏,服務(wù)器接收相對較慢串绩,看下實驗的結(jié)果
a. 包175,發(fā)送ACK攜帶WIN = 384枉圃,告知客戶端功茴,現(xiàn)在只能接收384個字節(jié)
b. 包176,客戶端果真只發(fā)送了384個字節(jié)孽亲,Wireshark也比較智能坎穿,也宣告TCP Window Full
c. 包177,服務(wù)器回復一個ACK返劲,并通告窗口為0玲昧,說明接收方已經(jīng)收到所有數(shù)據(jù),并保存到緩沖區(qū)篮绿,但是這個時候應(yīng)用程序并沒有接收這些數(shù)據(jù)孵延,導致緩沖區(qū)沒有更多的空間,故通告窗口為0, 這也就是所謂的零窗口亲配,零窗口期間尘应,發(fā)送方停止發(fā)送數(shù)據(jù)
d. 客戶端察覺到窗口為0惶凝,則不再發(fā)送數(shù)據(jù)給接收方
e. 包178,接收方發(fā)送一個窗口通告犬钢,告知發(fā)送方已經(jīng)有接收數(shù)據(jù)的能力了梨睁,可以發(fā)送數(shù)據(jù)包了
f. 包179,收到窗口通告之后娜饵,就發(fā)送緩沖區(qū)內(nèi)的數(shù)據(jù)了.
3 TCP擁塞控制機制
擁塞控制的算法有:慢開始坡贺、擁塞避免、快重傳箱舞、快恢復四種遍坟。
擁塞的標志:重傳計時器超時、接收到三個重復確認晴股。
控制機制:
快重傳:
面試題:
騰訊面試題
TCP的擁塞控制機制是什么愿伴?請簡單說說。
答:我們知道TCP通過一個定時器(timer)采樣了RTT并計算RTO电湘,但是隔节,如果網(wǎng)絡(luò)上的延時突然增加,那么寂呛,TCP對這個事做出的應(yīng)對只有重傳數(shù)據(jù)怎诫,然而重傳會導致網(wǎng)絡(luò)的負擔更重,于是會導致更大的延遲以及更多的丟包贷痪,這就導致了惡性循環(huán)幻妓,最終形成“網(wǎng)絡(luò)風暴” —— TCP的擁塞控制機制就是用于應(yīng)對這種情況。
首先需要了解一個概念劫拢,為了在發(fā)送端調(diào)節(jié)所要發(fā)送的數(shù)據(jù)量肉津,定義了一個“擁塞窗口”(Congestion Window),在發(fā)送數(shù)據(jù)時舱沧,將擁塞窗口的大小與接收端ack的窗口大小做比較妹沙,取較小者作為發(fā)送數(shù)據(jù)量的上限。
擁塞控制主要是四個算法:
1.慢啟動:意思是剛剛加入網(wǎng)絡(luò)的連接熟吏,一點一點地提速距糖,不要一上來就把路占滿。
連接建好的開始先初始化cwnd = 1分俯,表明可以傳一個MSS大小的數(shù)據(jù)肾筐。
每當收到一個ACK,cwnd++; 呈線性上升
每當過了一個RTT缸剪,cwnd = cwnd*2; 呈指數(shù)讓升
閾值ssthresh(slow start threshold)吗铐,是一個上限,當cwnd >= ssthresh時杏节,就會進入“擁塞避免算法”
2.擁塞避免:當擁塞窗口 cwnd 達到一個閾值時唬渗,窗口大小不再呈指數(shù)上升典阵,而是以線性上升,避免增長過快導致網(wǎng)絡(luò)擁塞镊逝。
每當收到一個ACK壮啊,cwnd = cwnd + 1/cwnd
每當過了一個RTT,cwnd = cwnd + 1
擁塞發(fā)生:當發(fā)生丟包進行數(shù)據(jù)包重傳時撑蒜,表示網(wǎng)絡(luò)已經(jīng)擁塞歹啼。分兩種情況進行處理:
等到RTO超時,重傳數(shù)據(jù)包
sshthresh = cwnd /2
cwnd 重置為 1
3.進入慢啟動過程
在收到3個duplicate ACK時就開啟重傳座菠,而不用等到RTO超時
sshthresh = cwnd = cwnd /2
進入快速恢復算法——Fast Recovery
4.快速恢復:至少收到了3個Duplicated Acks狸眼,說明網(wǎng)絡(luò)也不那么糟糕,可以快速恢復浴滴。
cwnd = sshthresh + 3 * MSS (3的意思是確認有3個數(shù)據(jù)包被收到了)
重傳Duplicated ACKs指定的數(shù)據(jù)包
如果再收到 duplicated Acks拓萌,那么cwnd = cwnd +1
如果收到了新的Ack,那么升略,cwnd = sshthresh 微王,然后就進入了擁塞避免的算法了。
4 socket模型
image.png
套接字的幾個函數(shù)對應(yīng)的TCP操作
image.png
socket
創(chuàng)建套接字品嚣,指定要使用的地址簇(ip)和套接字類型/傳輸層協(xié)議(tcp)炕倘,返回一個套接字描述符,簡稱sockfd腰根,用于在函數(shù)調(diào)用(connect激才、read 等)中標識這個套接字。
bind
將一個 本地IP:本地端口 賦值給一個套接字额嘿,限定該套接字只接收目的地為指定的本地IP、端口的客戶連接劣挫。進程指定册养。
linsen
僅由 TCP server 調(diào)用。當 socket 函數(shù)創(chuàng)建了套接字压固,會假設(shè)為主動套接字球拦,也就是將調(diào)用 connect 主動發(fā)起連接的套接字。linsen 將一個未連接的套接字轉(zhuǎn)換成被動套接字帐我,通知內(nèi)核應(yīng)該接受指向該套接字的連接請求(被動打開)坎炼。此時套接字的狀態(tài)從 CLOSED 轉(zhuǎn)到 LISTEN。
內(nèi)核為每個監(jiān)聽套接字維護兩個隊列:
未完成連接隊列拦键,收到了客戶的 SYN谣光,正在等待 TCP 三次握手完成。此時套接字的狀態(tài)為 SYN_RCVD芬为。
已完成連接隊列萄金,已經(jīng)完成 TCP 三次握手的客戶蟀悦,這些套接字處于 ESTABLISHED 狀態(tài)。
當收到客戶的SYN氧敢,TCP在未完成連接隊列中創(chuàng)建一項新條目日戈,同時繼承監(jiān)聽套接字的參數(shù),然后返回SYS孙乖、ACK浙炼,這一項一直保留在未完成連接隊列中,直到收到 ACK唯袄,或者該項超時弯屈。如果三次握手正常完成,該項從未完成連接隊列移到已完成連接隊列的隊尾越妈。
指定 backlog季俩,即兩個隊列長度之和。
image.png
accept
僅由 TCP server 調(diào)用梅掠,從已完成連接的隊頭獲得一個已完成連接酌住,如果已完成連接的隊列為空,進程被掛起進入睡眠狀態(tài)(假定套接字為默認的阻塞方式)阎抒,直到隊列中有條目酪我。
接收監(jiān)聽套接字描述符,返回 由內(nèi)核自動為獲得的已完成連接生成的已連接套接字描述符且叁,以及對應(yīng)的已連接套接字都哭。
connect
僅由 TCP client 調(diào)用,接收 socket 返回的套接字描述符逞带,主動向 TCP server 發(fā)送建立連接的請求(主動打開)欺矫,觸發(fā)三次握手。調(diào)用 connect 之前不一定要調(diào)用 bind 綁定本地ip 和 本地端口展氓,這樣穆趴,內(nèi)核會通過數(shù)據(jù)出口確定源ip,并選定一個臨時端口作為源端口遇汞。
- TCP UDP區(qū)別
1未妹、基于連接與無連接;
2空入、對系統(tǒng)資源的要求(TCP較多络它,UDP少);
3歪赢、UDP程序結(jié)構(gòu)較簡單化戳;
4、流模式與數(shù)據(jù)報模式 轨淌;
5迂烁、TCP保證數(shù)據(jù)正確性看尼,UDP可能丟包;
6盟步、TCP保證數(shù)據(jù)順序藏斩,UDP不保證。 - Time_Wait中2*msl 為什么
如果TIME_WAIT狀態(tài)保持時間不足夠長却盘,第一個連接就正常終止了狰域。第二個擁有相同五元組的連接出現(xiàn),而第一個連接的重復報文到達黄橘,干擾了第二個連接兆览。TCP事先必須防止某個連接的重復報文在連接終止后出現(xiàn),所以讓TIME_WAIT狀態(tài)保持時間足夠長(2MSL)塞关,連接相應(yīng)方向的上的TCP報文要么完全響應(yīng)完畢抬探,要么被丟棄。建立第二個連接的時候帆赢,不會混淆小压。 - 一個url從輸入到訪問經(jīng)過了哪些過程
1.DNS 解析:將域名解析成 IP 地址
2.TCP 連接:TCP 三次握手
3.發(fā)送 HTTP 請求
4.服務(wù)器處理請求并返回 HTTP 報文
5.瀏覽器解析渲染頁面
6.斷開連接:TCP 四次揮手