TCP協(xié)議
TCP,即Transmission Control Protocol,傳輸控制協(xié)議.
TCP協(xié)議數(shù)據(jù)格式
- 16位源端口號(hào)與16位目的端口號(hào)表示數(shù)據(jù)從那個(gè)進(jìn)程來(lái)要到那個(gè)進(jìn)程去.
- 32位序號(hào)表示一次TCP通信(從TCP連接建立到斷開)過(guò)程中某一個(gè)傳輸方向上的字節(jié)流的每個(gè)字節(jié)的編號(hào)(TCP將每個(gè)字節(jié)的數(shù)據(jù)都進(jìn)行了編號(hào),稱為序列號(hào)).
- 32為確認(rèn)序號(hào)表示接收方對(duì)發(fā)送的tcp報(bào)文段的響應(yīng)。 其值是收到的TCP報(bào)文段的序號(hào)值加1.
- 4位TCP報(bào)文長(zhǎng)度表示該TCP頭部有多少個(gè)32位bit(有多少個(gè)4字節(jié)),所以TCP頭部最大長(zhǎng)度是15 * 4 = 60字節(jié).
6位標(biāo)志位:
URG:表示緊急指針是否有效
ACK:確認(rèn)號(hào)是否有效
PSH:提示接收端應(yīng)用程序立刻從TCP緩沖區(qū)把數(shù)據(jù)讀走
RST:表示復(fù)位連接,也就是重新建立連接
SYN:表示同步,把攜帶SYN標(biāo)識(shí)的稱為同步報(bào)文
FIN:通知對(duì)方,本端要關(guān)閉了,我們稱攜帶FIN標(biāo)識(shí)的為結(jié)束報(bào)文段
- 16位窗口大小:表示接收端TCP 能最大提供65535個(gè)字節(jié)的緩沖.
- 16位校驗(yàn)和:發(fā)送方通過(guò)以TCP報(bào)頭與報(bào)文數(shù)據(jù)進(jìn)行一定數(shù)學(xué)計(jì)算得到的結(jié)果填充于此,接收方以相同數(shù)學(xué)方法進(jìn)行計(jì)算,如果校驗(yàn)和相同則校驗(yàn)成功.
- 16位緊急指針:標(biāo)識(shí)哪部分?jǐn)?shù)據(jù)是緊急數(shù)據(jù).
TCP原理
確認(rèn)應(yīng)答
接收到發(fā)送方的數(shù)據(jù)后,會(huì)返回發(fā)送一個(gè)帶有接收數(shù)據(jù)的最后一個(gè)字節(jié)的下一個(gè)字節(jié)序號(hào)的ACK報(bào)文.
比如接收到的最后一個(gè)字節(jié)序號(hào)為1000,則返回的序號(hào)為1001,代表前1000個(gè)字節(jié)數(shù)據(jù)已經(jīng)全部收到.
為解決后發(fā)先至,tcp會(huì)有一個(gè)接收緩沖區(qū)(內(nèi)核中的內(nèi)存空間),每個(gè)socket都有一份自己的接受緩沖區(qū),tcp可在緩沖區(qū)對(duì)收到的消息根據(jù)序列號(hào)進(jìn)行整隊(duì).
超時(shí)重傳
網(wǎng)絡(luò)傳輸可能會(huì)出現(xiàn)丟包的情況:
- 發(fā)送的數(shù)據(jù)報(bào)接受方?jīng)]有收到
- 接受方收到后,發(fā)回的ack報(bào)文傳輸過(guò)程中丟失.
應(yīng)對(duì)策略
發(fā)送方?jīng)]有收到ack應(yīng)答報(bào)文,就會(huì)隔一段時(shí)間進(jìn)行報(bào)文重發(fā),隨著重發(fā)次數(shù)的增加,間隔時(shí)間也會(huì)增長(zhǎng),連續(xù)多次重傳后還是無(wú)法獲取ack報(bào)文,此時(shí)tcp就會(huì)嘗試重置連接,如果重置失敗,則會(huì)釋放連接(TCP為了保證無(wú)論在任何環(huán)境下都能比較高性能的通信,因此會(huì)動(dòng)態(tài)計(jì)算這個(gè)最大超時(shí)時(shí)間).
如果收到重發(fā)數(shù)據(jù),數(shù)據(jù)重復(fù),tcp會(huì)根據(jù)收的數(shù)據(jù)序號(hào)自動(dòng)進(jìn)行去重
問(wèn)tcp如何實(shí)現(xiàn)可靠性的?
答:確認(rèn)應(yīng)答+超時(shí)重傳
連接管理
三次握手
上述過(guò)程由內(nèi)核自動(dòng)完成,應(yīng)用程序干預(yù)不了.
握手?的是通信雙方進(jìn)行一次網(wǎng)絡(luò)交互,相當(dāng)于客戶端與服務(wù)器端,通過(guò)三次交互,建立了連接(雙方各自記錄對(duì)方的信息)
三次握手的目的就是為了投石問(wèn)路,驗(yàn)證客戶端和服務(wù)器端,各自的發(fā)送能力與接受能力是否正常!
客戶端向服務(wù)器發(fā)送SYN報(bào)文問(wèn)服務(wù)器你準(zhǔn)備好了沒,服務(wù)器返回SYN+ACK報(bào)文說(shuō)我準(zhǔn)備好了,你呢?客戶端發(fā)送ACK告訴服務(wù)器我準(zhǔn)備好了,到此連接建立成功.
四次揮手
進(jìn)行斷開連接,斷開連接服務(wù)器與客戶端都有可能先進(jìn)行發(fā)起FIN結(jié)束報(bào)文.
為什么是四次揮手而不是三次揮手呢?
ack與fin有一定概率合并成為一個(gè)的!!但通常情況下不能合并!
ack與fin是不會(huì)同時(shí)觸發(fā)的,因?yàn)閍ck是系統(tǒng)內(nèi)核完成的,而fin而是由應(yīng)用程序來(lái)進(jìn)行控制的,調(diào)用socket的close方法才會(huì)觸發(fā)fin!!!
滑動(dòng)窗口
發(fā)送方一次發(fā)多條數(shù)據(jù)到一定程度停止發(fā)送,發(fā)送方一次等待多個(gè)ack,收到一條ack報(bào)文發(fā)送一條數(shù)據(jù),形似一個(gè)滑動(dòng)的窗口.
出現(xiàn)丟包情況:
- 數(shù)據(jù)包到達(dá),ACK報(bào)文丟失
這種情況沒啥影響,只要最后幾個(gè)ack報(bào)文收到,就表明前面的ack也都收到了(確認(rèn)序號(hào)的含義表示的是該序號(hào)之前的所有數(shù)據(jù)都已經(jīng)收到). - 數(shù)據(jù)包未到達(dá)
如果是這種情況,應(yīng)答報(bào)文一直顯示已經(jīng)接受到了1001,1001到2000會(huì)超時(shí)重傳,而后面數(shù)據(jù)的接受是不會(huì)受影響的,當(dāng)1001到2000接受到后,會(huì)直接返回已接受數(shù)據(jù)的最后一個(gè)字節(jié)的下一個(gè)字節(jié)的序號(hào).
上述超時(shí)重傳稱為快述重傳.
流量控制
本質(zhì)就是讓接收方來(lái)限制一下發(fā)送方的速度-根據(jù)接收端的處理能力,來(lái)決定發(fā)送端的發(fā)送速度.
當(dāng)ACK報(bào)文頭部的ack位為1時(shí),報(bào)頭的窗口大小字段就會(huì)生效,返回一個(gè)窗口大小來(lái)決定發(fā)送方發(fā)送的速度.
當(dāng)發(fā)送方,發(fā)現(xiàn)對(duì)方接收緩沖區(qū)滿了之后,就會(huì)暫停發(fā)送,但仍然會(huì)每隔一段時(shí)間觸發(fā)一個(gè)"窗口探測(cè)"報(bào)文,如果探測(cè)一會(huì)發(fā)現(xiàn)窗口大小不為0,則繼續(xù)發(fā)送.
擁塞控制
TCP引入 慢啟動(dòng) 機(jī)制,先發(fā)少量的數(shù)據(jù),探探路,摸清當(dāng)前的網(wǎng)絡(luò)擁堵狀態(tài),再?zèng)Q定按照多大的速度傳輸數(shù)據(jù).
衡量了傳輸路徑的處理能力–木桶效應(yīng)(傳輸路勁上某一個(gè)路由器可用傳輸速率很小,那么這個(gè)路由器的傳輸能力即為傳輸路徑上的最大傳輸能力)
通過(guò)實(shí)驗(yàn)的方式,找到一個(gè)合適的發(fā)射速率–先開始以一個(gè)較小的速率發(fā)送,不丟包的情況下提高速率,如果丟包,立即調(diào)小速率. 達(dá)到一個(gè)動(dòng)態(tài)平衡.
實(shí)際發(fā)送的窗口大小=將擁塞窗口和接收端主機(jī)反饋的窗口大小(流量控制窗口)做比較,取較小的值作為
實(shí)際發(fā)送的窗口
此圖描述: 擁塞窗口先以一個(gè)較小值進(jìn)行傳輸,無(wú)丟包情況下速率開始以指數(shù)形式增長(zhǎng),達(dá)到一定閾值后以線性進(jìn)行增長(zhǎng)(避免一下子超過(guò)上限很多),當(dāng)開始出現(xiàn)丟包情況時(shí)認(rèn)為當(dāng)前窗口已達(dá)路徑上限,且窗口回到一個(gè)較小值,閾值更新為為上限的一半;
延遲應(yīng)答
延時(shí)應(yīng)答的核心在于讓ACK應(yīng)答報(bào)文稍微延時(shí)一會(huì)兒應(yīng)答,那么此時(shí)應(yīng)答報(bào)文中的接受方緩沖區(qū)大小大概率比立即返回大一點(diǎn)(應(yīng)用程序一直從接收緩沖區(qū)讀取數(shù)據(jù)),此時(shí)發(fā)送方可發(fā)送的數(shù)據(jù)就會(huì)多一點(diǎn).
窗口越大,網(wǎng)絡(luò)吞吐量就越大,傳輸效率就越高,在保證網(wǎng)絡(luò)不擁塞的情況下盡量提高傳輸效率
數(shù)量限制:每隔N個(gè)包就應(yīng)答一次;
時(shí)間限制:超過(guò)最大延遲時(shí)間就應(yīng)答一次;
捎帶應(yīng)答
接收方的應(yīng)答報(bào)文ack稍等一會(huì)接收方的響應(yīng)報(bào)文 二者合并為一個(gè)數(shù)據(jù)報(bào)進(jìn)行發(fā)送可提高效率.
捎帶應(yīng)答的效果----四次揮手有可呢三次揮完.
面向字節(jié)流
粘包問(wèn)題
A連續(xù)給B發(fā)送了多個(gè)應(yīng)用層數(shù)據(jù)報(bào),這些數(shù)據(jù)就會(huì)堆積在B的接收緩沖區(qū),此時(shí)B的應(yīng)用程序再去讀這些數(shù)據(jù)報(bào)就會(huì)很難分清楚那個(gè)是一個(gè)完整的數(shù)據(jù)報(bào),很容易讀半個(gè)(在TCP的協(xié)議頭中,沒有如同UDP一樣的 “報(bào)文長(zhǎng)度” 這樣的字段,站在應(yīng)用層的角度,看到的只是一串連續(xù)的字節(jié)數(shù)據(jù),不知道從哪個(gè)部分開始到哪個(gè)部分,是一個(gè)完整的應(yīng)用層數(shù)據(jù)包).
解決方法:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-429604.html
- 約定分割符.
- 約定長(zhǎng)度(例如約定數(shù)據(jù)的前四個(gè)字節(jié),用來(lái)表示數(shù)據(jù)報(bào)的長(zhǎng)度).
異常問(wèn)題
- 進(jìn)程關(guān)閉/進(jìn)程崩潰
進(jìn)程沒有了,socket是文件,隨之關(guān)閉,雖然進(jìn)程沒有了,但是連接還在,可進(jìn)行正常四次揮手. - 主機(jī)關(guān)機(jī)
所有用戶進(jìn)程被關(guān)閉,觸發(fā)四次揮手,如果沒有揮完,比如服務(wù)器端發(fā)來(lái)fin ,客戶端沒來(lái)及ack就關(guān)機(jī)了.
此時(shí)對(duì)端就會(huì)重轉(zhuǎn)fin…重傳幾次后發(fā)現(xiàn)沒有ack后嘗試重置連接,沒有成功后就釋放連接. - 斷電/斷網(wǎng)
- 如果對(duì)方是發(fā)送方
對(duì)方就會(huì)收不到ack=>超時(shí)重傳->重置連接->釋放連接 - 如果對(duì)方是接受端
對(duì)方是無(wú)法立即知道,你這邊是沒來(lái)得及發(fā)數(shù)據(jù)還是直接沒了
這使tcp的心眺包 ?;顧C(jī)制就體現(xiàn)作用了
- 如果對(duì)方是發(fā)送方
接收方定期給發(fā)送方發(fā)送一個(gè)心跳包如果有響應(yīng)就說(shuō)明對(duì)端還存活,如果沒有響應(yīng)而說(shuō)明對(duì)端已經(jīng)掛了(心跳包時(shí)周期性的并沒有那么及時(shí),并且判斷也沒有那么嚴(yán)格).文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-429604.html
到了這里,關(guān)于JavaEE-輕松了解網(wǎng)絡(luò)原理之TCP協(xié)議的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!