目錄
1. TCP協(xié)議頭部格式
2. TCP協(xié)議原理?
2.1 可靠傳輸機(jī)制
2.1.1 確認(rèn)應(yīng)答機(jī)制
2.1.2 超時(shí)重傳機(jī)制
2.1.3 連接管理機(jī)制(三次握手,四次揮手)
2.1.4 流量控制
2.1.5 擁塞控制?
2.2 效率機(jī)制?
2.2.1 滑動(dòng)窗口?
2.2.2 延遲應(yīng)答?
2.2.3 捎帶應(yīng)答?
3. 粘包問(wèn)題?
4. TCP的異常情況?
5. TCP協(xié)議特點(diǎn)總結(jié)
6. 基于TCP的應(yīng)用層協(xié)議?
1. TCP協(xié)議頭部格式
- 源/目的端口:表示數(shù)據(jù)從哪個(gè)進(jìn)程發(fā)送,發(fā)送到哪個(gè)進(jìn)程去
- 32位序號(hào):發(fā)送的數(shù)據(jù)按照一個(gè)字節(jié)一個(gè)編號(hào)存放進(jìn)去
- 32位確認(rèn)號(hào):用于給對(duì)方的響應(yīng),值為收到TCP報(bào)文段的序號(hào)值加1(表示當(dāng)前的應(yīng)答報(bào)文針對(duì)的是哪個(gè)消息進(jìn)行的確認(rèn)應(yīng)答)
- 4位TCP報(bào)頭長(zhǎng)度:表示TCP頭部有4個(gè)字節(jié)(32位),所以TCP頭部最大長(zhǎng)度為15*4=60
- 6個(gè)boolean值標(biāo)志位:
URG:緊急指針是否有效
ACK:確認(rèn)號(hào)是否有效
PSH:提示接收端應(yīng)用程序立刻從TCP緩沖區(qū)把數(shù)據(jù)讀走
RST:對(duì)方要求重新建立連接,把攜帶RST標(biāo)識(shí)的稱為復(fù)位報(bào)文段
SYN:請(qǐng)求建立連接,把攜帶SYN標(biāo)識(shí)的稱為同步報(bào)文段
FIN:通知對(duì)方,要關(guān)閉連接了,把攜帶FIN標(biāo)識(shí)的稱為結(jié)束報(bào)文
- 16位窗口大?。哼M(jìn)行流量窗口控制
- 16位校驗(yàn)和:檢驗(yàn)數(shù)據(jù)是否一致
- 16位緊急指針:標(biāo)識(shí)哪部分?jǐn)?shù)據(jù)是緊急數(shù)據(jù)
2. TCP協(xié)議原理?
TCP協(xié)議是對(duì)數(shù)據(jù)傳輸提供的一個(gè)管控機(jī)制,主要體現(xiàn)在可靠和效率兩個(gè)方面,即在保證數(shù)據(jù)可靠傳輸?shù)那闆r下盡可能的提高效率?
2.1 可靠傳輸機(jī)制
2.1.1 確認(rèn)應(yīng)答機(jī)制
向?qū)Ψ桨l(fā)送一個(gè)數(shù)據(jù)報(bào),對(duì)方要返回一個(gè)確認(rèn)應(yīng)答的數(shù)據(jù)報(bào)?
實(shí)現(xiàn)的方式:序號(hào)和確認(rèn)序號(hào)保證了響應(yīng)應(yīng)答針對(duì)的是哪一條消息的應(yīng)答
說(shuō)明:
- 發(fā)送的數(shù)據(jù)是基于TCP報(bào)頭中的“32位序號(hào)”來(lái)保存的,一個(gè)字節(jié)對(duì)應(yīng)一個(gè)序號(hào)
- 確認(rèn)應(yīng)答的數(shù)據(jù)是基于TCP報(bào)頭中的“32位確認(rèn)序號(hào)”來(lái)保存的,ack(確認(rèn)信息)標(biāo)志位置為1,返回某個(gè)序列號(hào),說(shuō)明某個(gè)序列號(hào)之前的數(shù)據(jù)全部接收到
- 有了確認(rèn)應(yīng)答,它才可以繼續(xù)發(fā)送后邊的數(shù)據(jù)
2.1.2 超時(shí)重傳機(jī)制
發(fā)送的數(shù)據(jù)報(bào)可能因?yàn)榫W(wǎng)絡(luò)擁堵等原因,超過(guò)一定時(shí)間,還沒(méi)有收到確認(rèn)應(yīng)答的數(shù)據(jù)報(bào),就需要重新發(fā)送?
- 沒(méi)有收到確認(rèn)應(yīng)答,可能是因?yàn)榘l(fā)送數(shù)據(jù)時(shí)候就已經(jīng)發(fā)生了丟包
??
- 也可能是因?yàn)锳CK丟包了?
?
這種情況,主機(jī)B可能會(huì)接收到許多重復(fù)的數(shù)據(jù),TCP內(nèi)部有去重操作,接收的數(shù)據(jù)會(huì)放在操作系統(tǒng)內(nèi)核的接收緩沖區(qū)中,接收緩沖區(qū)可以是一個(gè)內(nèi)存空間,視為是一個(gè)阻塞隊(duì)列,對(duì)于收到的數(shù)據(jù),TCP會(huì)根據(jù)序號(hào)檢查這個(gè)數(shù)據(jù)是不是在緩沖區(qū)中已經(jīng)存在,如果存在則丟棄,如果不存在則放進(jìn)去
超時(shí)時(shí)間如何確定?
如果超時(shí)時(shí)間設(shè)置的太長(zhǎng),會(huì)導(dǎo)致重傳的效率
如果超時(shí)時(shí)間設(shè)置的太短,會(huì)導(dǎo)致頻繁發(fā)送重復(fù)的數(shù)據(jù)
因此TCP協(xié)議為了保證在任何環(huán)境中都能有較高性能的通信,系統(tǒng)會(huì)動(dòng)態(tài)的計(jì)算這個(gè)超時(shí)時(shí)間
- 超時(shí)以500ms為一個(gè)單位,每次判定超時(shí)重發(fā)的時(shí)間都是500ms的整數(shù)倍
- 重發(fā)一次,仍然不能收到應(yīng)答,等待2*500ms后再進(jìn)行重傳
- 仍然等不到應(yīng)答,等待4*500ms進(jìn)行重傳,以此類推,以指數(shù)形式增長(zhǎng)
- 累積到一定重傳次數(shù),TCP協(xié)議認(rèn)為網(wǎng)絡(luò)或者對(duì)端主機(jī)出現(xiàn)異常,強(qiáng)制關(guān)閉連接
2.1.3 連接管理機(jī)制(三次握手,四次揮手)
真正發(fā)送數(shù)據(jù)之前,要先通過(guò)三次握手建立連接,不需要發(fā)送數(shù)據(jù)了,通過(guò)四次揮手?jǐn)嚅_(kāi)連接
三次握手
??
- 客戶端向服務(wù)端發(fā)送SYN,申請(qǐng)建立客戶端到服務(wù)端的連接
- 服務(wù)端返回ACK(第一次SYN的應(yīng)答)和SYN,申請(qǐng)建立服務(wù)端到客戶端的連接
- 客戶端收到數(shù)據(jù),狀態(tài)置為ESTABLISHED,表示客戶端到服務(wù)端連接建立完成,并且發(fā)送ACK(第二次SYN的應(yīng)答),服務(wù)端收到數(shù)據(jù),狀態(tài)置為ESTABLISHED,表示服務(wù)端到客戶端的連接建立完成
三次握手主要是為了檢查當(dāng)前網(wǎng)絡(luò)的情況是否滿足可靠運(yùn)輸?shù)幕緱l件,同時(shí)也是在檢測(cè)雙方發(fā)送和接收數(shù)據(jù)的能力是否正常?
四次揮手?
說(shuō)明:關(guān)閉的時(shí)候服務(wù)端申請(qǐng)關(guān)閉或者客戶端申請(qǐng)關(guān)閉都可以
- 客戶端發(fā)送FIN到服務(wù)端,申請(qǐng)關(guān)閉客戶端到服務(wù)端的連接
- 服務(wù)端收到FIN狀態(tài)置為CLOSE_WAIT,并返回ACK應(yīng)答(這個(gè)動(dòng)作是系統(tǒng)實(shí)現(xiàn)TCP協(xié)議棧默認(rèn)執(zhí)行的,不需要程序來(lái)調(diào)用代碼)
- 服務(wù)端發(fā)送FIN到客戶端,申請(qǐng)關(guān)閉服務(wù)端到客戶端的連接(程序手動(dòng)調(diào)用socket.close發(fā)送)
- 客戶端收到FIN返回ACK應(yīng)答,并進(jìn)入TIME_WAIT時(shí)間等待狀態(tài),客戶端等待一段時(shí)間后,狀態(tài)置為CLOSED,服務(wù)端收到應(yīng)答后,狀態(tài)置為CLOSED
思考:
- 為什么服務(wù)端不將ACK和FIN合并一起發(fā)送,形成三次揮手呢?
答:主要是ACK和FIN的發(fā)送時(shí)機(jī)不同,ACK是操作系統(tǒng)內(nèi)核響應(yīng)的(立即執(zhí)行),而此時(shí)服務(wù)端還可能在繼續(xù)發(fā)送數(shù)據(jù),待處理完數(shù)據(jù)后由程序調(diào)用close方法后才發(fā)送FIN
- 為什么客戶端要等待一段時(shí)間狀態(tài)才置為CLOSED,而不之間將狀態(tài)置為CLOSED?
答:如果客戶端給服務(wù)端的ACK丟包后,服務(wù)端得重新給和客戶端發(fā)送FIN,此時(shí)客戶端得給服務(wù)端應(yīng)答,所以此時(shí)狀態(tài)不能置為CLOSED,得等待一段時(shí)間(2MSL,MSL為網(wǎng)絡(luò)上任意兩點(diǎn)傳輸?shù)淖畲髸r(shí)間)確保服務(wù)端收到客戶端的應(yīng)答?
2.1.4 流量控制
接收端主機(jī)處理數(shù)據(jù)的速度有限,如果發(fā)送端發(fā)送數(shù)據(jù)太快,導(dǎo)致接收端緩沖區(qū)被填滿,這時(shí),發(fā)送端繼續(xù)發(fā)送數(shù)據(jù)的話就會(huì)造成丟包,繼而引起丟包重傳等一些列連鎖反應(yīng),因此TCP協(xié)議根據(jù)接收端接收數(shù)據(jù)的能力,來(lái)決定發(fā)送端發(fā)送數(shù)據(jù)的速度,這個(gè)機(jī)制就叫作流量控制?
- 接收端將自己剩余緩沖區(qū)大小存入TCP頭部中的“16位窗口大小”字段?,通過(guò)ACK通知發(fā)送端
- 窗口大小越大,說(shuō)明網(wǎng)絡(luò)吞吐量越高
- 發(fā)送端根據(jù)接收到這個(gè)窗口的大小,控制自己的發(fā)送速度
- 如果接收緩沖區(qū)滿了,就會(huì)將窗口設(shè)置為0,這時(shí),發(fā)送端不在發(fā)送數(shù)據(jù),而是定期的發(fā)送一個(gè)窗口探測(cè)報(bào)文(只是為了知道窗口的大?。?,讓接收端將窗口大小告訴發(fā)送端
2.1.5 擁塞控制?
剛開(kāi)始發(fā)送數(shù)據(jù)時(shí),由于中間結(jié)點(diǎn)的網(wǎng)絡(luò)情況不清楚,如果貿(mào)然發(fā)送大量數(shù)據(jù),就會(huì)造成大量丟包,所以TCP協(xié)議引入慢啟動(dòng)的方式,先發(fā)少量數(shù)據(jù)探探路,再?zèng)Q定按照多大速度發(fā)送數(shù)據(jù)
此處引入擁塞窗口,剛開(kāi)始時(shí),擁塞窗口設(shè)置為1,每收到一個(gè)ACK時(shí),擁塞窗口加1,每次發(fā)送數(shù)據(jù)的時(shí)候,擁塞窗口和流量窗口的較小的值作為實(shí)際發(fā)送的窗口,即滑動(dòng)窗口的大小?
注意:上述增長(zhǎng)方式是指數(shù)級(jí)別的,指數(shù)式增長(zhǎng)可以快速接近丟包的極限
擁塞窗口變化的方式?
為了不增長(zhǎng)那么快,引入一個(gè)慢啟動(dòng)的閾值,當(dāng)擁塞窗口的大小超過(guò)了這個(gè)閾值,不在按照指數(shù)方式增長(zhǎng),而是按照線性方式增長(zhǎng),如下圖所示:
開(kāi)始時(shí),慢啟動(dòng)的閾值為窗口的最大值,線性增長(zhǎng)到一定程度時(shí)會(huì)發(fā)生丟包
網(wǎng)絡(luò)擁塞時(shí),擁塞窗口置1,慢啟動(dòng)閾值變?yōu)閾砣翱?2,重新開(kāi)始增長(zhǎng)
2.2 效率機(jī)制?
2.2.1 滑動(dòng)窗口?
前面的確認(rèn)應(yīng)答機(jī)制指出,對(duì)每一個(gè)發(fā)送的數(shù)據(jù)都對(duì)應(yīng)有一個(gè)ACK確認(rèn)應(yīng)答,這樣采取一發(fā)一收的方式有一個(gè)很大的缺點(diǎn)就是效率太差,為了提高效率采用滑動(dòng)窗口,即一次性發(fā)送多個(gè)數(shù)據(jù)
- 窗口大?。褐笩o(wú)需等待而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值,上圖的窗口大小為4000個(gè)字節(jié)(四個(gè)段)
- 具體如何設(shè)置窗口大小:min(流量窗口的大小,擁塞窗口的大小)?
- 窗口如何滑動(dòng):接收到的ACK下一個(gè)是n,滑動(dòng)到n-1的位置
操作系統(tǒng)內(nèi)核為了維護(hù)這個(gè)滑動(dòng)窗口,需要開(kāi)辟發(fā)送緩沖區(qū)來(lái)記錄當(dāng)前還有哪些數(shù)據(jù)沒(méi)有應(yīng)答,只有應(yīng)答過(guò)的數(shù)據(jù)才能從緩沖區(qū)中刪掉
如果出現(xiàn)了丟包,如何確保可靠傳輸?
- 情況一:數(shù)據(jù)已經(jīng)收到,返回的ACK應(yīng)答丟包
這種情況下,部分ACK丟了不要緊,因?yàn)榭梢酝ㄟ^(guò)后續(xù)的ACK進(jìn)行確認(rèn)?
- 情況二:發(fā)送數(shù)據(jù)的時(shí)候就已經(jīng)丟包?
說(shuō)明:
- 當(dāng)1001~2000這段報(bào)文丟失后,發(fā)送端一直會(huì)收到1001這樣的ACK
- 如果發(fā)送端主機(jī)連續(xù)三次收到相同的ACK如1001應(yīng)答,那發(fā)送端主機(jī)就會(huì)重新發(fā)送1001~2000數(shù)據(jù)
- 此時(shí),接收端收到1001~2000數(shù)據(jù)后,再次返回的ACK應(yīng)答就是7001了,因?yàn)?001~7000數(shù)據(jù)都已經(jīng)接收到了,被放到接收端操作系統(tǒng)內(nèi)核的接收緩沖區(qū)了
這種機(jī)制,即時(shí)不超時(shí)也會(huì)發(fā)生重傳,稱作“高速重發(fā)控制”也叫“快重傳機(jī)制”?
2.2.2 延遲應(yīng)答?
如果接收端主機(jī)接收到數(shù)據(jù)時(shí),立刻返回ACK應(yīng)答,這時(shí)候返回的流量窗口就比較小,但是流量窗口越大,網(wǎng)絡(luò)吞吐量越大,傳輸效率就越高,所以等待一部分時(shí)間,待接收端處理完一部分?jǐn)?shù)據(jù)?,就可以將流量窗口設(shè)置為大一點(diǎn)的值,這樣網(wǎng)咯吞吐量大,效率高
延遲是為了高吞吐量,但是也不能無(wú)限延遲
- 數(shù)量限制,每隔n個(gè)包就應(yīng)答一次
- 時(shí)間限制,超過(guò)最大延遲時(shí)間,就應(yīng)答一次
具體的數(shù)量和時(shí)間,不同操作系統(tǒng)有差異,一般n取2,超時(shí)時(shí)間取200ms?
2.2.3 捎帶應(yīng)答?
服務(wù)端接收到客戶端的消息后,因?yàn)檠舆t應(yīng)答機(jī)制,導(dǎo)致ACK不一定立即返回,可能ACK返回的時(shí)機(jī)和應(yīng)用代碼中返回響應(yīng)的時(shí)機(jī)重合了,此時(shí)九江
3. 粘包問(wèn)題?
TCP是面向字節(jié)流的,可以多次的接收和發(fā)送,對(duì)于應(yīng)用層來(lái)說(shuō),一連串的字節(jié)數(shù)據(jù),不知道從哪到哪算一個(gè)完整的應(yīng)用層數(shù)據(jù)包,對(duì)應(yīng)發(fā)送多少次算一個(gè)應(yīng)用層完整格式的數(shù)據(jù),和接收多少次算一個(gè)應(yīng)用層完整格式的數(shù)據(jù)就不知道了
如何解決粘包問(wèn)題?明確包的邊界文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-802317.html
- 對(duì)于定長(zhǎng)的包,每次都按照固定大小讀取即可
- 對(duì)于變長(zhǎng)的包,可以在包與包之間明確分隔符(應(yīng)用協(xié)議,程序員自己定,只要保證分隔符和正文不起沖突即可)?
4. TCP的異常情況?
- 進(jìn)程終止:進(jìn)程終止會(huì)釋放文件描述符,仍然可以發(fā)送FIN,和正常關(guān)閉沒(méi)有什么區(qū)別
- 機(jī)器重啟:和進(jìn)程終止的情況相同
- 機(jī)器掉電/網(wǎng)線斷開(kāi):接收端認(rèn)為連接還在,一旦接收端有寫(xiě)入操作,接收端發(fā)現(xiàn)連接已經(jīng)不在了就會(huì)進(jìn)行reset,即使沒(méi)有寫(xiě)入操作,TCP自己也內(nèi)置了一個(gè)?;疃〞r(shí)器,會(huì)定期詢問(wèn)對(duì)方是否還在,如果對(duì)方不在,也會(huì)把連接釋放
- 另外,應(yīng)用層的某些協(xié)議,也有一些這樣的檢測(cè)機(jī)制,例如HTTP長(zhǎng)連接中,也會(huì)定期檢測(cè)對(duì)方的狀態(tài),例如QQ,在QQ斷線之后,也會(huì)定期嘗試重新連接?
5. TCP協(xié)議特點(diǎn)總結(jié)
- 有連接:通過(guò)三次握手建立連接后才可接發(fā)數(shù)據(jù),TCP協(xié)議是全雙工的,即每端既可以發(fā)也可以收
- 可靠傳輸:網(wǎng)絡(luò)數(shù)據(jù)傳輸是一跳一跳的,經(jīng)過(guò)路途中的設(shè)備可能發(fā)生數(shù)據(jù)丟失,可靠傳輸是可能發(fā)生數(shù)據(jù)丟失但有機(jī)制保證對(duì)方能接收到
- 面向字節(jié)流:可以多次的收發(fā)數(shù)據(jù)(連接沒(méi)有關(guān)閉時(shí),可以多次的接收和發(fā)送數(shù)據(jù))
- 有接收緩沖區(qū)和發(fā)送緩沖區(qū):發(fā)送數(shù)據(jù)時(shí),是先寫(xiě)到發(fā)送緩沖區(qū),再刷新緩沖區(qū)(flush)
- 大小不受限制:多次的收發(fā)數(shù)據(jù),每次的數(shù)據(jù)可以很大?
6. 基于TCP的應(yīng)用層協(xié)議?
- HTTP
- HTTPS
- SSH
- Telnet
- FTP
- SMTP
也包括自己寫(xiě)TCP程序時(shí)自定義的應(yīng)用層協(xié)議?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-802317.html
到了這里,關(guān)于【計(jì)算機(jī)網(wǎng)絡(luò)】TCP協(xié)議詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!