日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

图解TCPIP协议

發(fā)布時(shí)間:2023/12/9 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解TCPIP协议 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • 本文原文鏈接通過(guò)兩個(gè)圖來(lái)梳理TCP-IP協(xié)議相關(guān)知識(shí)。TCP通信過(guò)程包括三個(gè)步驟:建立TCP連接通道,傳輸數(shù)據(jù),斷開(kāi)TCP連接通道。如圖1所示,給出了TCP通信過(guò)程的示意圖。

    圖1主要包括三部分:建立連接傳輸數(shù)據(jù)斷開(kāi)連接

    建立TCP連接很簡(jiǎn)單,通過(guò)三次握手便可建立連接。

    建立好連接后,開(kāi)始傳輸數(shù)據(jù)。TCP數(shù)據(jù)傳輸牽涉到的概念很多:超時(shí)重傳快速重傳流量控制擁塞控制等等。

    斷開(kāi)連接的過(guò)程也很簡(jiǎn)單,通過(guò)四次握手完成斷開(kāi)連接的過(guò)程。

    三次握手建立連接

    第一次握手:客戶端發(fā)送syn包(seq=x)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);

    第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=x+1),同時(shí)自己也發(fā)送一個(gè)SYN包(seq=y),即SYN+ACK包,此時(shí)服務(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),完成三次握手。

    握手過(guò)程中傳送的包里不包含數(shù)據(jù),三次握手完畢后,客戶端與服務(wù)器才正式開(kāi)始傳送數(shù)據(jù)。理想狀態(tài)下,TCP連接一旦建立,在通信雙方中的任何一方主動(dòng)關(guān)閉連接之前,TCP 連接都將被一直保持下去。

    傳輸數(shù)據(jù)過(guò)程:

    超時(shí)重傳

    超時(shí)重傳機(jī)制用來(lái)保證TCP傳輸?shù)目煽啃浴C看伟l(fā)送數(shù)據(jù)包時(shí),發(fā)送的數(shù)據(jù)報(bào)都有seq號(hào),接收端收到數(shù)據(jù)后,會(huì)回復(fù)ack進(jìn)行確認(rèn),表示某一seq號(hào)數(shù)據(jù)已經(jīng)收到。發(fā)送方在發(fā)送了某個(gè)seq包后,等待一段時(shí)間,如果沒(méi)有收到對(duì)應(yīng)的ack回復(fù),就會(huì)認(rèn)為報(bào)文丟失,會(huì)重傳這個(gè)數(shù)據(jù)包。

    快速重傳

    接受數(shù)據(jù)一方發(fā)現(xiàn)有數(shù)據(jù)包丟掉了。就會(huì)發(fā)送ack報(bào)文告訴發(fā)送端重傳丟失的報(bào)文。如果發(fā)送端連續(xù)收到標(biāo)號(hào)相同的ack包,則會(huì)觸發(fā)客戶端的快速重傳(不用等到超時(shí)計(jì)時(shí)器結(jié)束即可確認(rèn)數(shù)據(jù)包已經(jīng)丟失)。比較超時(shí)重傳和快速重傳,可以發(fā)現(xiàn)超時(shí)重傳是發(fā)送端在傻等超時(shí),然后觸發(fā)重傳;而快速重傳則是接收端主動(dòng)告訴發(fā)送端數(shù)據(jù)沒(méi)收到,然后觸發(fā)發(fā)送端重傳。

    流量控制

    這里主要說(shuō)TCP滑動(dòng)窗流量控制。TCP頭里有一個(gè)字段叫Window,又叫Advertised-Window,這個(gè)字段是接收端告訴發(fā)送端自己還有多少緩沖區(qū)可以接收數(shù)據(jù)。于是發(fā)送端就可以根據(jù)這個(gè)接收端的處理能力來(lái)發(fā)送數(shù)據(jù),而不會(huì)導(dǎo)致接收端處理不過(guò)來(lái)。 滑動(dòng)窗可以是提高TCP傳輸效率的一種機(jī)制。

    擁塞控制

    滑動(dòng)窗用來(lái)做流量控制。流量控制只關(guān)注發(fā)送端和接受端自身的狀況,而沒(méi)有考慮整個(gè)網(wǎng)絡(luò)的通信情況。擁塞控制,則是基于整個(gè)網(wǎng)絡(luò)來(lái)考慮的。考慮一下這樣的場(chǎng)景:某一時(shí)刻網(wǎng)絡(luò)上的延時(shí)突然增加,那么,TCP對(duì)這個(gè)事做出的應(yīng)對(duì)只有重傳數(shù)據(jù),但是,重傳會(huì)導(dǎo)致網(wǎng)絡(luò)的負(fù)擔(dān)更重,于是會(huì)導(dǎo)致更大的延遲以及更多的丟包,于是,這個(gè)情況就會(huì)進(jìn)入惡性循環(huán)被不斷地放大。試想一下,如果一個(gè)網(wǎng)絡(luò)內(nèi)有成千上萬(wàn)的TCP連接都這么行事,那么馬上就會(huì)形成“網(wǎng)絡(luò)風(fēng)暴”,TCP這個(gè)協(xié)議就會(huì)拖垮整個(gè)網(wǎng)絡(luò)。為此,TCP引入了擁塞控制策略。擁塞策略算法主要包括:慢啟動(dòng)擁塞避免擁塞發(fā)生快速恢復(fù)

    四次握手?jǐn)嚅_(kāi)連接

    第一次揮手:主動(dòng)關(guān)閉方發(fā)送一個(gè)FIN,用來(lái)關(guān)閉主動(dòng)方到被動(dòng)關(guān)閉方的數(shù)據(jù)傳送,也就是主動(dòng)關(guān)閉方告訴被動(dòng)關(guān)閉方:我已經(jīng)不會(huì)再給你發(fā)數(shù)據(jù)了(當(dāng)然,在fin包之前發(fā)送出去的數(shù)據(jù),如果沒(méi)有收到對(duì)應(yīng)的ack確認(rèn)報(bào)文,主動(dòng)關(guān)閉方依然會(huì)重發(fā)這些數(shù)據(jù)),但此時(shí)主動(dòng)關(guān)閉方還可以接受數(shù)據(jù)。

    第二次揮手:被動(dòng)關(guān)閉方收到FIN包后,發(fā)送一個(gè)ACK給對(duì)方,確認(rèn)序號(hào)為收到序號(hào)+1(與SYN相同,一個(gè)FIN占用一個(gè)序號(hào))。

    第三次揮手:被動(dòng)關(guān)閉方發(fā)送一個(gè)FIN,用來(lái)關(guān)閉被動(dòng)關(guān)閉方到主動(dòng)關(guān)閉方的數(shù)據(jù)傳送,也就是告訴主動(dòng)關(guān)閉方,我的數(shù)據(jù)也發(fā)送完了,不會(huì)再給你發(fā)數(shù)據(jù)了。

    第四次揮手:主動(dòng)關(guān)閉方收到FIN后,發(fā)送一個(gè)ACK給被動(dòng)關(guān)閉方,確認(rèn)序號(hào)為收到序號(hào)+1,至此,完成四次揮手。

    狀態(tài)轉(zhuǎn)換圖

    圖2給出了TCP通信過(guò)程中的狀態(tài)轉(zhuǎn)移圖,理解此圖是我們理解TCP-IP協(xié)議的關(guān)鍵。

    狀態(tài)圖詳細(xì)解讀:

    CLOSED:起始點(diǎn),在超時(shí)或者連接關(guān)閉時(shí)候進(jìn)入此狀態(tài)。

    LISTEN:服務(wù)端在等待連接過(guò)來(lái)時(shí)候的狀態(tài),服務(wù)端為此要調(diào)用socket,bind,listen函數(shù),就能進(jìn)入此狀態(tài)。此稱(chēng)為應(yīng)用程序被動(dòng)打開(kāi)(等待客戶端來(lái)連接)。

    SYN_SENT:客戶端發(fā)起連接,發(fā)送SYN給服務(wù)器端。如果服務(wù)器端不能連接,則直接進(jìn)入CLOSED狀態(tài)。

    SYN_RCVD:跟3對(duì)應(yīng),服務(wù)器端接受客戶端的SYN請(qǐng)求,服務(wù)器端由LISTEN狀態(tài)進(jìn)入SYN_RCVD狀態(tài)。同時(shí)服務(wù)器端要回應(yīng)一個(gè)ACK,同時(shí)發(fā)送一個(gè)SYN給客戶端;另外一種情況,客戶端在發(fā)起SYN的同時(shí)接收到服務(wù)器端得SYN請(qǐng)求,客戶端就會(huì)由SYN_SENT到SYN_RCVD狀態(tài)。

    ESTABLISHED:服務(wù)器端和客戶端在完成3次握手進(jìn)入狀態(tài),說(shuō)明已經(jīng)可以開(kāi)始傳輸數(shù)據(jù)了。

    以上是建立連接時(shí)服務(wù)器端和客戶端產(chǎn)生的狀態(tài)轉(zhuǎn)移說(shuō)明。相對(duì)來(lái)說(shuō)比較簡(jiǎn)單明了,如果你對(duì)三次握手比較熟悉,建立連接時(shí)的狀態(tài)轉(zhuǎn)移還是很容易理解。

    下面,我們來(lái)看看連接關(guān)閉時(shí)候的狀態(tài)轉(zhuǎn)移說(shuō)明,關(guān)閉需要進(jìn)行4次雙方的交互,還包括要處理一些善后工作(TIME_WAIT狀態(tài)),注意,這里主動(dòng)關(guān)閉的一方或被動(dòng)關(guān)閉的一方不是指特指服務(wù)器端或者客戶端,是相對(duì)于誰(shuí)先發(fā)起關(guān)閉請(qǐng)求來(lái)說(shuō)的:

    FIN_WAIT_1:主動(dòng)關(guān)閉的一方,由狀態(tài)5進(jìn)入此狀態(tài)。具體的動(dòng)作是發(fā)送FIN給對(duì)方。

    FIN_WAIT_2:主動(dòng)關(guān)閉的一方,接收到對(duì)方的FIN-ACK(即fin包的回應(yīng)包),進(jìn)入此狀態(tài)。

    CLOSE_WAIT:接收到FIN以后,被動(dòng)關(guān)閉的一方進(jìn)入此狀態(tài)。具體動(dòng)作是接收到FIN,同時(shí)發(fā)送ACK。(之所以叫close_wait可以理解為被動(dòng)關(guān)閉方此時(shí)正在等待上層應(yīng)用發(fā)出關(guān)閉連接指令)

    LAST_ACK:被動(dòng)關(guān)閉的一方,發(fā)起關(guān)閉請(qǐng)求,由狀態(tài)8進(jìn)入此狀態(tài)。具體動(dòng)作是發(fā)送FIN給對(duì)方,同時(shí)在接收到ACK時(shí)進(jìn)入CLOSED狀態(tài)。

    CLOSING:兩邊同時(shí)發(fā)起關(guān)閉請(qǐng)求時(shí),會(huì)由FIN_WAIT_1進(jìn)入此狀態(tài)。具體動(dòng)作是接收到FIN請(qǐng)求,同時(shí)響應(yīng)一個(gè)ACK。

    TIME_WAIT:最糾結(jié)的狀態(tài)來(lái)了。從狀態(tài)圖上可以看出,有3個(gè)狀態(tài)可以轉(zhuǎn)化成它,我們一一來(lái)分析:?
    a. 由FIN_WAIT_2進(jìn)入此狀態(tài):在雙方不同時(shí)發(fā)起FIN的情況下,主動(dòng)關(guān)閉的一方在完成自身發(fā)起的關(guān)閉請(qǐng)求后,接收到被動(dòng)關(guān)閉一方的FIN后進(jìn)入的狀態(tài)。?
    b. 由CLOSING狀態(tài)進(jìn)入:雙方同時(shí)發(fā)起關(guān)閉,都做了發(fā)起FIN的請(qǐng)求,同時(shí)接收到了FIN并做了ACK的情況下,由CLOSING狀態(tài)進(jìn)入。?
    c. 由FIN_WAIT_1狀態(tài)進(jìn)入:同時(shí)接受到FIN(對(duì)方發(fā)起),ACK(本身發(fā)起的FIN回應(yīng)),與b的區(qū)別在于本身發(fā)起的FIN回應(yīng)的ACK先于對(duì)方的FIN請(qǐng)求到達(dá),而b是FIN先到達(dá)。這種情況概率最小。

    關(guān)閉的4次連接最難理解的狀態(tài)是TIME_WAIT,存在TIME_WAIT的2個(gè)理由:

    可靠地實(shí)現(xiàn)TCP全雙工連接的終止。 允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝。

    附:

    慢熱啟動(dòng)算法 – Slow Start

    首先,我們來(lái)看一下TCP的慢熱啟動(dòng)。慢啟動(dòng)的意思是,剛剛加入網(wǎng)絡(luò)的連接,一點(diǎn)一點(diǎn)地提速,不要一上來(lái)就像那些特權(quán)車(chē)一樣霸道地把路占滿。新同學(xué)上高速還是要慢一點(diǎn),不要把已經(jīng)在高速上的秩序給搞亂了。

    慢啟動(dòng)的算法如下(cwnd全稱(chēng)Congestion Window):

    1)連接建好的開(kāi)始先初始化cwnd = 1,表明可以傳一個(gè)MSS大小的數(shù)據(jù)。

    2)每當(dāng)收到一個(gè)ACK,cwnd++; 呈線性上升

    3)每當(dāng)過(guò)了一個(gè)RTT,cwnd = cwnd*2; 呈指數(shù)讓升

    4)還有一個(gè)ssthresh(slow start threshold),是一個(gè)上限,當(dāng)cwnd >= ssthresh時(shí),就會(huì)進(jìn)入“擁塞避免算法”(后面會(huì)說(shuō)這個(gè)算法)

    所以,我們可以看到,如果網(wǎng)速很快的話,ACK也會(huì)返回得快,RTT也會(huì)短,那么,這個(gè)慢啟動(dòng)就一點(diǎn)也不慢。

    擁塞避免算法 – Congestion Avoidance

    前面說(shuō)過(guò),還有一個(gè)ssthresh(slow start threshold),是一個(gè)上限,當(dāng)cwnd >= ssthresh時(shí),就會(huì)進(jìn)入“擁塞避免算法”。一般來(lái)說(shuō)ssthresh的值是65535,單位是字節(jié),當(dāng)cwnd達(dá)到這個(gè)值時(shí)后,算法如下:

    1)收到一個(gè)ACK時(shí),cwnd = cwnd + 1/cwnd

    2)當(dāng)每過(guò)一個(gè)RTT時(shí),cwnd = cwnd + 1

    這樣就可以避免增長(zhǎng)過(guò)快導(dǎo)致網(wǎng)絡(luò)擁塞,慢慢的增加調(diào)整到網(wǎng)絡(luò)的最佳值。很明顯,是一個(gè)線性上升的算法。

    擁塞狀態(tài)時(shí)的算法

    前面我們說(shuō)過(guò),當(dāng)丟包的時(shí)候,會(huì)有兩種情況:

    1)等到RTO超時(shí),重傳數(shù)據(jù)包。TCP認(rèn)為這種情況太糟糕,反應(yīng)也很強(qiáng)烈。

    view sourceprint?

    1.<code?class=" hljs fix">sshthresh =? cwnd /2

    2.cwnd 重置為?1

    3.進(jìn)入慢啟動(dòng)過(guò)程</code>

    2)Fast Retransmit算法,也就是在收到3個(gè)duplicate ACK時(shí)就開(kāi)啟重傳,而不用等到RTO超時(shí)。

    TCP Tahoe的實(shí)現(xiàn)和RTO超時(shí)一樣。

    view sourceprint?

    1.<code?class=" hljs makefile">TCP Reno的實(shí)現(xiàn)是:

    2.cwnd = cwnd /2

    3.sshthresh = cwnd

    4.進(jìn)入快速恢復(fù)算法——Fast Recovery</code>

    上面我們可以看到RTO超時(shí)后,sshthresh會(huì)變成cwnd的一半,這意味著,如果cwnd<=sshthresh時(shí)出現(xiàn)的丟包,那么TCP的sshthresh就會(huì)減了一半,然后等cwnd又很快地以指數(shù)級(jí)增漲爬到這個(gè)地方時(shí),就會(huì)成慢慢的線性增漲。我們可以看到,TCP是怎么通過(guò)這種強(qiáng)烈地震蕩快速而小心得找到網(wǎng)站流量的平衡點(diǎn)的。

    快速恢復(fù)算法 – Fast Recovery

    這個(gè)算法定義在RFC5681。快速重傳和快速恢復(fù)算法一般同時(shí)使用。快速恢復(fù)算法是認(rèn)為,你還有3個(gè)Duplicated Acks說(shuō)明網(wǎng)絡(luò)也不那么糟糕,所以沒(méi)有必要像RTO超時(shí)那么強(qiáng)烈。 注意,正如前面所說(shuō),進(jìn)入Fast Recovery之前,cwnd和sshthresh已被更新:

    view sourceprint?

    1.<code?class=" hljs ini">cwnd = cwnd /2

    2.sshthresh = cwnd</code>

    然后,真正的Fast Recovery算法如下:

    cwnd = sshthresh + 3 * MSS(3的意思是確認(rèn)有3個(gè)數(shù)據(jù)包被收到了)?
    重傳Duplicated ACKs指定的數(shù)據(jù)包.如果再收到 duplicated Acks,那么cwnd = cwnd +1。如果收到了新的Ack,那么,cwnd = sshthresh ,然后就進(jìn)入了擁塞避免的算法了。

    如果你仔細(xì)思考一下上面的這個(gè)算法,你就會(huì)知道,上面這個(gè)算法也有問(wèn)題,那就是——它依賴于3個(gè)重復(fù)的Acks。注意,3個(gè)重復(fù)的Acks并不代表只丟了一個(gè)數(shù)據(jù)包,很有可能是丟了好多包。但這個(gè)算法只會(huì)重傳一個(gè),而剩下的那些包只能等到RTO超時(shí),于是,進(jìn)入了惡夢(mèng)模式——超時(shí)一個(gè)窗口就減半一下,多個(gè)超時(shí)會(huì)超成TCP的傳輸速度呈級(jí)數(shù)下降,而且也不會(huì)觸發(fā)Fast Recovery算法了。

    TCP New Reno

    于是,1995年,TCP New Reno(參見(jiàn)RFC 6582)算法提出來(lái),主要就是在沒(méi)有SACK的支持下改進(jìn)Fast Recovery算法的——?
    當(dāng)sender這邊收到了3個(gè)Duplicated Acks,進(jìn)入Fast Retransimit模式,開(kāi)發(fā)重傳重復(fù)Acks指示的那個(gè)包。如果只有這一個(gè)包丟了,那么,重傳這個(gè)包后回來(lái)的Ack會(huì)把整個(gè)已經(jīng)被sender傳輸出去的數(shù)據(jù)ack回來(lái)。如果沒(méi)有的話,說(shuō)明有多個(gè)包丟了。我們叫這個(gè)ACK為Partial ACK。

    一旦Sender這邊發(fā)現(xiàn)了Partial ACK出現(xiàn),那么,sender就可以推理出來(lái)有多個(gè)包被丟了,于是乎繼續(xù)重傳sliding window里未被ack的第一個(gè)包。直到再也收不到了Partial Ack,才真正結(jié)束Fast Recovery這個(gè)過(guò)程。

    我們可以看到,這個(gè)“Fast Recovery的變更”是一個(gè)非常激進(jìn)的玩法,他同時(shí)延長(zhǎng)了Fast Retransmit和Fast Recovery的過(guò)程。

術(shù)語(yǔ):

SYN表示建立連接,

FIN表示關(guān)閉連接,

ACK表示響應(yīng),

PSH表示有 DATA數(shù)據(jù)傳輸,

RST表示連接重置。

http://www.cnblogs.com/azraelly/archive/2012/12/25/2832393.html

轉(zhuǎn)載于:https://blog.51cto.com/danniea/1642489

總結(jié)

以上是生活随笔為你收集整理的图解TCPIP协议的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。