目錄
一.TCP概念及其特性? ? ??
二.TCP原理
1.確認(rèn)應(yīng)答機(jī)制
2.超時(shí)重傳機(jī)制
3.連接管理機(jī)制
三次握手的過程
四次揮手?jǐn)嚅_連接過程
四次揮手?jǐn)嚅_連接變形情況:
為什么連接階段時(shí)三次握手,斷開連接是四次揮手??
服務(wù)器上面出現(xiàn)大量的CLOSE_WAIT狀態(tài)的TCP連接,請(qǐng)問這種現(xiàn)象是否合理?
既然主動(dòng)關(guān)閉端揮手的工作已經(jīng)完成了,為什么還有TIME_WAIT狀態(tài)而不直接進(jìn)入CLOSED狀態(tài)?
為什么是TIME_WAIT的時(shí)間是2MSL?
4.流量控制
5.滑動(dòng)窗口機(jī)制
那如果在傳輸數(shù)據(jù)時(shí)出現(xiàn)了數(shù)據(jù)丟失,如何進(jìn)行重傳?
?6.擁塞控制
7.延遲應(yīng)答機(jī)制
8.捎帶應(yīng)答機(jī)制
一.TCP概念及其特性? ? ??
傳輸控制協(xié)議:TCP(Transmission Control Protocol)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,在簡(jiǎn)化的計(jì)算機(jī)網(wǎng)絡(luò)OSI模型中,它完成第四層傳輸層所指定的功能。 用戶數(shù)據(jù)報(bào)協(xié)議(UDP)是同一層內(nèi)另一個(gè)重要的傳輸協(xié)議。
特性:可靠性,有連接,面向字節(jié)流
什么是可靠性:
1.TCP會(huì)盡自己所能,盡量將數(shù)據(jù)發(fā)送給對(duì)方
2.TCP匯集那個(gè)數(shù)據(jù)沒有發(fā)給對(duì)方的情況下,給應(yīng)用層一個(gè)錯(cuò)誤通知
3.TCP可以保證接收方(應(yīng)用層)嚴(yán)格按照發(fā)送時(shí)的順序接收
4.TCP保證數(shù)據(jù)不會(huì)無意間的損壞
5.TCP盡可能的維護(hù)網(wǎng)絡(luò)質(zhì)量 ?
二.TCP原理
1.確認(rèn)應(yīng)答機(jī)制
發(fā)送方發(fā)送數(shù)據(jù),如果收到了接收方的應(yīng)答(確認(rèn)),就代表了接收方收到了數(shù)據(jù);
如果超過一定時(shí)間沒有收到接收方的應(yīng)答(確認(rèn)),可以推測(cè)接收方未能收到數(shù)據(jù)。
*如果發(fā)送方同時(shí)發(fā)送了多條數(shù)據(jù),如何確認(rèn)接收方的確認(rèn)信息是指的那一條數(shù)據(jù)?
答:對(duì)數(shù)據(jù)進(jìn)行編號(hào),接收方發(fā)出確認(rèn)信息的時(shí)候也帶上編號(hào),就可以明確接受的數(shù)據(jù)。
對(duì)數(shù)據(jù)進(jìn)行編號(hào)
1.發(fā)送的數(shù)據(jù)編號(hào)——序列號(hào)? SN(Sequence Number)??
2.確認(rèn)時(shí)的數(shù)據(jù)編號(hào)——確認(rèn)序列號(hào)? ASN(Acknowledge Sequence Number)
3.初始序列號(hào)ISN(initial sequence number):在 TCP 建立連接的時(shí)候,客戶端和服務(wù)端都會(huì)各自生成一個(gè)初始序列號(hào),它是基于時(shí)鐘生成的一個(gè)隨機(jī)數(shù),來保證每個(gè)連接都擁有不同的初始序列號(hào)。
* 如果超過一定時(shí)間沒有收到接收方的確認(rèn),該如何操作?
答:進(jìn)行重發(fā)。進(jìn)行重發(fā)需要觸發(fā)的條件:超過一定時(shí)間沒有收到接收方的確認(rèn)
2.超時(shí)重傳機(jī)制
先思考:如果沒有收到對(duì)方發(fā)送的應(yīng)答,可能的情況有哪些
????????1.對(duì)方?jīng)]有收到你的數(shù)據(jù)所以沒有應(yīng)答;又分為以下兩種情況
????????(1):數(shù)據(jù)還在路上,暫時(shí)還沒有到達(dá)對(duì)方
????????(2):數(shù)據(jù)在路上丟失了,所以不會(huì)有應(yīng)答
????????2.對(duì)方收到數(shù)據(jù)了發(fā)出來應(yīng)答,但是應(yīng)答我沒有收到;又分為以下兩種情況
????????(1):應(yīng)帶還在路上,我們暫時(shí)還沒有收到
????????(2):應(yīng)答在路上丟失,我們不會(huì)收到應(yīng)答
如果是上面1(1),2(1)這兩種情況,我們可以選擇合適的時(shí)間差進(jìn)行重發(fā);
如果是1(2),2(2)這兩種情況,我們是否能選擇重發(fā),還是需要進(jìn)一步的辨別?
????????答案是重發(fā),看看下面的分析:
????????主機(jī)A發(fā)送數(shù)據(jù)給B之后,可能因?yàn)榫W(wǎng)絡(luò)擁堵等原因,數(shù)據(jù)無法到達(dá)主機(jī)B;
????????如果主機(jī)A在一個(gè)特定時(shí)間間隔內(nèi)沒有收到B發(fā)來的確認(rèn)應(yīng)答,就會(huì)進(jìn)行重發(fā);
:
????????主機(jī)B會(huì)收到很多重復(fù)數(shù)據(jù)。那么TCP協(xié)議需要能夠識(shí)別出那些包是重復(fù)的包,并且把重復(fù)的丟棄掉。這時(shí)候我們可以利用前面發(fā)送數(shù)據(jù)時(shí)的序列號(hào),就可以很容易做到去重的效果。
那該如何選擇再次發(fā)送數(shù)據(jù)的時(shí)間?
????????這個(gè)時(shí)間的長(zhǎng)短,隨著網(wǎng)絡(luò)環(huán)境的不同,是有差異的。如果超時(shí)時(shí)間設(shè)的太長(zhǎng),會(huì)影響整體的重傳效率;如果超時(shí)時(shí)間設(shè)的太短,有可能會(huì)頻繁發(fā)送重復(fù)的包;
? ? ? ? 一般來說會(huì)略大于往返時(shí)間RRT(Round Trip Time),RTT需要進(jìn)行多次測(cè)量計(jì)算得來
新RTTS=(1?α)×舊RTTS+α×RTT
????????a的取值為:0≤α≤1,RFC推薦的αα值為1/8,即0.125。通過上面的公式得出的加權(quán)平均往返時(shí)間RTTs就比直接測(cè)量得出的RTT更加平滑。TCP為了保證無論在任何環(huán)境下都能比較高性能的通信,因此會(huì)動(dòng)態(tài)計(jì)算這個(gè)最大超時(shí)時(shí)間。
如果是網(wǎng)絡(luò)(物理層)出現(xiàn)問題,會(huì)一直的重發(fā)下去嗎?
????????不會(huì),TCP會(huì)嘗試重發(fā)幾次(重發(fā)的次數(shù)不同版本的操作系統(tǒng)會(huì)有不同),如果還是收不到應(yīng)答,就會(huì)停止發(fā)送。然后需要通知應(yīng)用層,發(fā)送失敗。
3.連接管理機(jī)制
在正常情況下,TCP要經(jīng)過三次握手建立連接,四次揮手?jǐn)嚅_連接。
三次握手的過程
TCP的主動(dòng)連接方一般為客戶端
TCP的被動(dòng)連接方一般為服務(wù)器
來看一看客戶端和服務(wù)器在三次握手中的狀態(tài)變化
客戶端:
CLOSED -> SYN_SENT :?客戶端調(diào)用connect,發(fā)送同步報(bào)文段;
SYN_SENT -> ESTABLISHED?: connect調(diào)用成功,則進(jìn)入ESTABLISHED狀態(tài),開始讀寫數(shù)
據(jù);
服務(wù)器:
CLOSED -> LISTEN:?服務(wù)器端調(diào)用listen后進(jìn)入LISTEN狀態(tài),等待客戶端連接;
LISTEN -> SYN_RCVD: 一旦監(jiān)聽到連接請(qǐng)求(同步報(bào)文段),就將該連接放入內(nèi)核等待隊(duì)列
中,并向客戶端發(fā)送SYN確認(rèn)報(bào)文。
SYN_RCVD -> ESTABLISHED:?服務(wù)端一旦收到客戶端的確認(rèn)報(bào)文,就進(jìn)入ESTABLISHED狀
態(tài),可以進(jìn)行讀寫數(shù)據(jù)了。
三次握手階段是否可以攜帶payload?
1.第一次握手,主動(dòng)連接方發(fā)送syn,不可以攜帶數(shù)據(jù)
2.第二次握手,被動(dòng)連接方發(fā)送syn+ack,不可以攜帶數(shù)據(jù)
3.第三次握手,主動(dòng)連接方發(fā)送ack,可以攜帶數(shù)據(jù)
?原因:因?yàn)樵诘谝淮魏偷诙挝帐蛛A段時(shí),不能確認(rèn)連接一定建立成功,如果攜帶了數(shù)據(jù),則會(huì)提升發(fā)送成本,還會(huì)接受失敗,所以TCP協(xié)議設(shè)計(jì)時(shí)禁止了攜帶數(shù)據(jù);第三次握手連接已經(jīng)建立成功,所以第三次握手可以發(fā)送數(shù)據(jù)。
?TCP三次握手階段SN與ASN的變換
主動(dòng)連接方初始化序列號(hào)為:ISN : a ;
被動(dòng)連接方初始化序列號(hào)為:ISN : b?;
?第一次握手階段 :syn? len = 0; SN = a ;ASN = 0;
第二次握手階段 :syn + ack len = 0; SN = b ; ASN = a+1;
第三次握手階段 : ack? len = ? ; SN = a+1 ; ASN = b+1;
由于第一二次握手階段不能攜帶數(shù)據(jù),所以len = 0;第三次握手階段中 "?"表示攜帶數(shù)據(jù)的長(zhǎng)度;
四次揮手?jǐn)嚅_連接過程
四次揮手?jǐn)嚅_連接的狀態(tài)變化
客戶端:
ESTABLISHED -> FIN_WAIT_1:?客戶端主動(dòng)調(diào)用close時(shí),向服務(wù)器發(fā)送結(jié)束報(bào)文段,同時(shí)進(jìn)
入FIN_WAIT_1;
FIN_WAIT_1 -> FIN_WAIT_2:?客戶端收到服務(wù)器對(duì)結(jié)束報(bào)文段的確認(rèn),則進(jìn)入FIN_WAIT_2,
開始等待服務(wù)器的結(jié)束報(bào)文段;
FIN_WAIT_2 -> TIME_WAIT:?客戶端收到服務(wù)器發(fā)來的結(jié)束報(bào)文段,進(jìn)入TIME_WAIT,并發(fā)
出LAST_ACK;
TIME_WAIT -> CLOSED:?客戶端要等待一個(gè)2MSL(Max Segment Life,報(bào)文最大生存時(shí)
間)的時(shí)間,才會(huì)進(jìn)入CLOSED狀態(tài)。
服務(wù)器:
ESTABLISHED -> CLOSE_WAIT:?當(dāng)客戶端主動(dòng)關(guān)閉連接(調(diào)用close),服務(wù)器會(huì)收到結(jié)束
報(bào)文段,服務(wù)器返回確認(rèn)報(bào)文段并進(jìn)入CLOSE_WAIT;
CLOSE_WAIT -> LAST_ACK:進(jìn)入CLOSE_WAIT后說明服務(wù)器準(zhǔn)備關(guān)閉連接(需要處理完之前
的數(shù)據(jù));當(dāng)服務(wù)器真正調(diào)用close關(guān)閉連接時(shí),會(huì)向客戶端發(fā)送FIN,此時(shí)服務(wù)器進(jìn)入
LAST_ACK狀態(tài),等待最后一個(gè)ACK到來(這個(gè)ACK是客戶端確認(rèn)收到了FIN)
LAST_ACK -> CLOSED:?服務(wù)器收到了對(duì)FIN的ACK,徹底關(guān)閉連接。
四次揮手?jǐn)嚅_連接變形情況:
三次揮手
?雙方同時(shí)揮手
為什么連接階段時(shí)三次握手,斷開連接是四次揮手??
????????當(dāng)收到對(duì)方的FIN報(bào)文通知時(shí),它僅僅表示對(duì)方?jīng)]有數(shù)據(jù)發(fā)送給你了;但未必你所有的數(shù)據(jù)都全部發(fā)送給對(duì)方了,所以你可能未必會(huì)馬上會(huì)關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對(duì)方之后,再發(fā)送FIN報(bào)文給對(duì)方來表示你同意現(xiàn)在可以關(guān)閉連接了,所以它這里的ACK報(bào)文和FIN報(bào)文多數(shù)情況下都是分開發(fā)送的。所以斷開連接是四次揮手
?*CLOSE_WAIT一定出現(xiàn)在單方面分手的被動(dòng)關(guān)閉端
服務(wù)器上面出現(xiàn)大量的CLOSE_WAIT狀態(tài)的TCP連接,請(qǐng)問這種現(xiàn)象是否合理?
? ? ? ? 無法確定是否合理;如果我們的程序設(shè)計(jì)時(shí),會(huì)出現(xiàn)比較長(zhǎng)時(shí)間的單方面關(guān)閉的情況時(shí),會(huì)出現(xiàn)大量CLOSE_WAIT是合理的現(xiàn)象,但如果我們沒有這種設(shè)計(jì),則不合理,可能出現(xiàn)的原因是忘記調(diào)用socket.close()方法。
TIME_WAIT 狀態(tài)發(fā)生在主動(dòng)關(guān)閉端,出現(xiàn)在基本揮手已經(jīng)結(jié)束的情況;
既然主動(dòng)關(guān)閉端揮手的工作已經(jīng)完成了,為什么還有TIME_WAIT狀態(tài)而不直接進(jìn)入CLOSED狀態(tài)?
? ? ? ?(1) TIME_WAIT存在的理由之一是盡可能護(hù)送最后的ACK達(dá)到對(duì)端。
? ? ? ? 因?yàn)椴荒艽_保發(fā)出去的ACK對(duì)方一定會(huì)收到,所以還需要等待一段時(shí)間,如果對(duì)方?jīng)]有收到ACK,主動(dòng)關(guān)閉端需要重發(fā)FIN,如果主動(dòng)關(guān)閉端處于CLOSED的狀態(tài),對(duì)方就無法收到最后的ACK。
? ? ? ? (2)為了使就得數(shù)據(jù)包在網(wǎng)絡(luò)中因過期而失效
????????假設(shè)沒有time_wait狀態(tài)時(shí),A剛剛與B斷開連接,C又以和A相同的ip和port和B建立起連接,TCP協(xié)議棧無法區(qū)分A和C是不同的連接, 這時(shí),A連接發(fā)送的數(shù)據(jù)到達(dá)B之后會(huì)被B的TCP傳輸層當(dāng)做當(dāng)下正常的連接發(fā)來的數(shù)據(jù)進(jìn)行處理。
為什么是TIME_WAIT的時(shí)間是2MSL?
????????MSL,Maximum Segment Lifetime,最大報(bào)文段生存時(shí)間。即任何TCP報(bào)文在網(wǎng)絡(luò)中存在的最大時(shí)長(zhǎng),如果超過這個(gè)時(shí)間,這個(gè)TCP報(bào)文就會(huì)被丟棄。
????????因?yàn)橹鲃?dòng)關(guān)閉端不知道對(duì)方是否能收到ACK應(yīng)答數(shù)據(jù)包,如果沒有收到ACK,會(huì)進(jìn)行重傳FIN,考慮最壞的一種情況:第四次揮手的ACK包的最大生存時(shí)長(zhǎng)(MSL)+服務(wù)端重傳的FIN包的最大生存時(shí)長(zhǎng)(MSL)=2MSL。
現(xiàn)象:服務(wù)器上發(fā)現(xiàn)了大量的TIME_WAIT狀態(tài)的TCP連接,是否合理?不合理,給出修復(fù)意見。
????????理論上是合理的,但是如果影響了導(dǎo)致了新連接創(chuàng)建失敗,就不太合理了
? ? ? ? 一般來說客戶端背負(fù)的連接比較少,服務(wù)器背負(fù)的連接遠(yuǎn)遠(yuǎn)多于客戶端。由于維護(hù)連接是需要成本的,所以不建議服務(wù)器去主動(dòng)關(guān)閉連接。
4.流量控制
接收端處理數(shù)據(jù)的速度是有限的。如果發(fā)送端發(fā)的太快,導(dǎo)致接收端的緩沖區(qū)被打滿,這個(gè)時(shí)候如果發(fā)送端繼續(xù)發(fā)送,就會(huì)造成丟包,繼而引起丟包重傳等等一系列連鎖反應(yīng)。
因此TCP支持根據(jù)接收端的處理能力,來決定發(fā)送端的發(fā)送速度。這個(gè)機(jī)制就叫做流量控制(Flow
Control);
?接受窗口:接收緩存區(qū)中剩余空間的大小
作為發(fā)送方,如何實(shí)時(shí)的知道接收方的接受能力?
? ? ? ? 1.發(fā)送Segment Header,將自己的的接收能力(接收窗口的大?。┨顚懙酱翱谧侄沃?,發(fā)送給對(duì)方;
????????2.TCP即使沒有數(shù)據(jù)發(fā)送時(shí) ,也會(huì)定期發(fā)送Segment Header ,傳遞最新的接受能力;
5.滑動(dòng)窗口機(jī)制
先了解一下發(fā)送緩沖區(qū)的邏輯部分
?連接建立階段,通過三次握手,就可以知道對(duì)方的接收窗口
?應(yīng)用層寫入了需要發(fā)送的數(shù)據(jù)
TCP發(fā)送一部分?jǐn)?shù)據(jù)給對(duì)方
?收到了來自接收方的應(yīng)答
? ? ? ? ? 橙色部分:已應(yīng)答部分,沒必要在保留,可以視為可用空間
紫色部分:發(fā)送為應(yīng)答部分
藍(lán)色部分:應(yīng)用層寫入的還未發(fā)送的數(shù)據(jù)
?了解這些知識(shí)后,再來看看滑動(dòng)窗口機(jī)制時(shí)如何實(shí)現(xiàn)的
? ? ? ?
?
應(yīng)用層寫入數(shù)據(jù)窗口增加,收到接收方的應(yīng)答后減小窗口,實(shí)現(xiàn)滑動(dòng)窗口機(jī)制。
那如果在傳輸數(shù)據(jù)時(shí)出現(xiàn)了數(shù)據(jù)丟失,如何進(jìn)行重傳?
分為兩種情況:
1.接收方的應(yīng)帶丟失
這種情況下,部分ACK丟了并不要緊,因?yàn)榭梢酝ㄟ^后續(xù)的ACK進(jìn)行確認(rèn);?
?2.發(fā)送數(shù)據(jù)的數(shù)據(jù)包丟失(快重傳機(jī)制)
????????當(dāng)某一段報(bào)文段丟失之后,發(fā)送端會(huì)一直收到 1001 這樣的ACK;
????????如果發(fā)送端主機(jī)連續(xù)三次收到了同樣一個(gè) "1001" 這樣的應(yīng)答,就會(huì)將對(duì)應(yīng)的數(shù)據(jù) 1001 -
2000 重新發(fā)送;
????????這個(gè)時(shí)候接收端收到了 1001 之后,再次返回的ACK就是7001了(因?yàn)?001 - 7000)接收端
其實(shí)之前就已經(jīng)收到了,被放到了接收端操作系統(tǒng)內(nèi)核的接收緩沖區(qū)中;?
????????這種機(jī)制被稱為 "高速重發(fā)控制"(也叫 "快重傳")。
?6.擁塞控制
????????網(wǎng)絡(luò)上有很多的計(jì)算機(jī),可能當(dāng)前的網(wǎng)絡(luò)狀態(tài)就已經(jīng)比較擁堵。在不清楚當(dāng)前網(wǎng)絡(luò)狀態(tài)下,如何發(fā)送數(shù)據(jù);
擁塞控制:根據(jù)網(wǎng)絡(luò)目前的承載能力來控制數(shù)據(jù)的發(fā)送量;
擁塞窗口 (cwnd):是發(fā)送方維護(hù)的一個(gè) 的狀態(tài)變量,它會(huì)根據(jù)網(wǎng)絡(luò)的擁塞程度動(dòng)態(tài)變化的。
橫坐標(biāo):時(shí)間
縱坐標(biāo):當(dāng)前計(jì)算出的擁塞窗口(cwnd)
慢開始:擁塞窗口的初始值非常小
指數(shù)增長(zhǎng)->線性增長(zhǎng)中間閾值(ssthresh) cwnd = cwnd^c ;上圖中(c 為1)
線性增長(zhǎng)->cwnd = cwnd + c(常數(shù))?
當(dāng)遇到了網(wǎng)絡(luò)擁塞,慢啟動(dòng)閾值會(huì)變成原來的一半,同時(shí)擁塞窗口(cwnd)置回1;
7.延遲應(yīng)答機(jī)制
?假設(shè)接收端緩沖區(qū)為1M。一次收到了500K的數(shù)據(jù);如果立刻應(yīng)答,返回的窗口就是500K;但實(shí)
際上可能處理端處理的速度很快,10ms之內(nèi)就把500K數(shù)據(jù)從緩沖區(qū)消費(fèi)掉了;在這種情況下,接
收端處理還遠(yuǎn)沒有達(dá)到自己的極限,即使窗口再放大一些,也能處理過來;如果接收端稍微等一會(huì)
再應(yīng)答,比如等待200ms再應(yīng)答,那么這個(gè)時(shí)候返回的窗口大小就是1M;
數(shù)量限制:每隔N個(gè)包就應(yīng)答一次;
時(shí)間限制:超過最大延遲時(shí)間就應(yīng)答一次;
具體的數(shù)量和超時(shí)時(shí)間,依操作系統(tǒng)不同也有差異;一般N取2,超時(shí)時(shí)間取200ms;
8.捎帶應(yīng)答機(jī)制
可以減少應(yīng)答次數(shù),將應(yīng)答和數(shù)據(jù)一起發(fā)送,提高效率。
文章來源:http://www.zghlxwxcb.cn/news/detail-456711.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-456711.html
到了這里,關(guān)于網(wǎng)絡(luò)原理——TCP協(xié)議的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!