TCP协议格式和特点
文章目錄
- 1.協(xié)議格式:
- 2.協(xié)議特性:
- 2.1 面向鏈接
- 2.1.1三次握手建立連接
- 2.1.1四次揮手?jǐn)嚅_(kāi)連接
- 相關(guān)問(wèn)題和知識(shí)點(diǎn):
- 1. 握手為啥三次,揮手是四次?
- 2. 三次握手失敗兩端是如何處理的?
- 3. SYN泛洪攻擊是怎么回事?
- 4. 一臺(tái)主機(jī)上出現(xiàn)了大量CLOSE_WAIT狀態(tài)鏈接是什么原因?
- 5. TIME_WAIT狀態(tài)有什么作用?
- 6. 一臺(tái)主機(jī)上出現(xiàn)大量TIME_WAIT鏈接,什么原因,怎么解決?
- 7. TCP的保活機(jī)制(心跳探測(cè))
- 2.2 可靠傳輸
- 2.2.1 安全有序傳輸(保證數(shù)據(jù)可靠到達(dá)對(duì)端并且有序進(jìn)行交付)
- 1. 確認(rèn)應(yīng)答機(jī)制
- 2. 超時(shí)重傳機(jī)制
- 3. 協(xié)議字段中的序號(hào)(th_seq)和確認(rèn)序號(hào)(th_ack)進(jìn)行包序管理,實(shí)現(xiàn)有序交付
- 4. 協(xié)議字段中的校驗(yàn)和校驗(yàn)數(shù)據(jù)一致性。
- 2.2.2 避免沒(méi)必要的丟包
- 1. 滑動(dòng)窗口機(jī)制
- 2. 擁塞窗口機(jī)制
- 2.2.3 提高一些傳輸性能
- 1. 確認(rèn)序號(hào)
- 2. 快速重傳協(xié)議
- 3. 捎帶應(yīng)答機(jī)制:
- 4. 延遲應(yīng)答機(jī)制
- 5. 延遲發(fā)送機(jī)制
- 2.3 面向字節(jié)流傳輸
- 3 對(duì)應(yīng)用層編程影響
- 問(wèn)題:tcp和udp協(xié)議的區(qū)別?
- tcp如何實(shí)現(xiàn)可靠傳輸
- udp如何實(shí)現(xiàn)可靠傳輸
TCP :傳輸控制協(xié)議
1.協(xié)議格式:
16位源端端口-16位對(duì)端端口:描述通信兩端
32位序號(hào)-32位確認(rèn)序號(hào):用于實(shí)現(xiàn)包序管理。
4位報(bào)頭長(zhǎng)度:描述tcp報(bào)頭長(zhǎng)度。4位表示最大數(shù)字15;以四字節(jié)為單位,所以TCp報(bào)頭最小長(zhǎng)度20字節(jié),最大為15 * 4 = 60字節(jié)。
6位保留
6位標(biāo)志位:
URG: 緊急指針是否有效ACK: 確認(rèn)應(yīng)答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位窗口大小:用于實(shí)現(xiàn)滑動(dòng)窗口機(jī)制–進(jìn)行發(fā)送數(shù)據(jù)的流量控制。防止緩沖區(qū)溢出丟包。
16為校驗(yàn)和:校驗(yàn)數(shù)據(jù)一致性。
16位緊急指針:發(fā)送的帶外數(shù)據(jù)的位置
0-40字節(jié)選項(xiàng)數(shù)據(jù):存儲(chǔ)一些可能需要的額外的信息。Mss…
應(yīng)用數(shù)據(jù)
2.協(xié)議特性:
2.1 面向鏈接
面向鏈接:通信雙方建立連接之后才能進(jìn)行通信,—>確保通信雙方都據(jù)有數(shù)據(jù)收發(fā)能力
TCP的鏈接管理:三次握手建立鏈接,四次揮手?jǐn)嚅_(kāi)鏈接。
主要是為了確認(rèn)通信雙方都在線有數(shù)據(jù)收發(fā)能力。
2.1.1三次握手建立連接
客戶端向服務(wù)端請(qǐng)求建立連接:
2.1.1四次揮手?jǐn)嚅_(kāi)連接
相關(guān)問(wèn)題和知識(shí)點(diǎn):
1. 握手為啥三次,揮手是四次?
三次握收:雙發(fā)都需要確定對(duì)方是否具有數(shù)據(jù)收發(fā)能力。兩次不安全—只能確定服務(wù)端在線,客戶端可能發(fā)送完SYN請(qǐng)求后就下線了。四次沒(méi)必要—SYN和ACK都是報(bào)文中的標(biāo)志位,分開(kāi)發(fā)送沒(méi)太大意義,直接將這兩個(gè)標(biāo)志位都置為1同時(shí)發(fā)送即可。
四次揮手:雙方上層只有在不會(huì)發(fā)送數(shù)據(jù)的情況下才會(huì)發(fā)送FIN(FIN表示上層不再發(fā)送數(shù)據(jù),但下層還能ACK確認(rèn)回復(fù))。收到FIN請(qǐng)求只能表示對(duì)方上層不再send發(fā)送數(shù)據(jù),不代表對(duì)方不能再收數(shù)據(jù)了。因此有可能接收FIN請(qǐng)求的一方還會(huì)繼續(xù)給對(duì)方發(fā)送數(shù)據(jù),只有在上層調(diào)用了close或者shutdown關(guān)閉寫(xiě)才會(huì)主動(dòng)給關(guān)閉方發(fā)FIN(不再發(fā)數(shù)據(jù)了).所以被動(dòng)關(guān)閉方的FIN和ACK默認(rèn)不一起發(fā)送。
2. 三次握手失敗兩端是如何處理的?
握手失敗情況:
1.SYN請(qǐng)求丟失,客戶端沒(méi)得到確認(rèn)回復(fù),隔一段時(shí)間會(huì)重新發(fā)送SYN請(qǐng)求。多次發(fā)送失敗會(huì)導(dǎo)致請(qǐng)求超時(shí),連接失敗。
2. 服務(wù)端發(fā)送的ACK+SYN信息丟失。客戶端沒(méi)收到SYN導(dǎo)致服務(wù)器沒(méi)收到相應(yīng)的的ACK回復(fù),新建的套接字會(huì)重新發(fā)送ACK+SYN請(qǐng)求。若服務(wù)端發(fā)送ACK+SYN請(qǐng)求超時(shí)(服務(wù)端可能會(huì)覺(jué)得這是惡意攻擊請(qǐng)求,只發(fā)起連接不回復(fù),占用資源),給客戶端發(fā)送RST重置連接報(bào)文,釋放新建套接字的資源。
3. 客戶端最后發(fā)送的ACK丟了。服務(wù)端等待超時(shí),服務(wù)端發(fā)送RST,釋放資源,從新建立連接。
3. SYN泛洪攻擊是怎么回事?
黑客偽造ip不斷向服務(wù)端發(fā)送SYN,但是不進(jìn)行ACK回復(fù),服務(wù)端新創(chuàng)建套接字會(huì)不斷占用資源,直至枯竭崩潰。所以listen(sockfd,backlog)接口中有backlog參數(shù)–新建連接隊(duì)列–隊(duì)列滿了就不會(huì)再新建套接字。處理方法:防火墻–同一ip頻繁發(fā)送數(shù)據(jù)則拉黑名單。
4. 一臺(tái)主機(jī)上出現(xiàn)了大量CLOSE_WAIT狀態(tài)鏈接是什么原因?
CLOSE_WAIT狀態(tài)是被動(dòng)關(guān)閉方收到FIN請(qǐng)求并進(jìn)行ACK回復(fù)之后進(jìn)入到的狀態(tài)。一旦自己發(fā)送了FIN(close操作后就會(huì)發(fā)送FIN)則會(huì)進(jìn)入下一個(gè)LAST_ACK狀態(tài),因此有大量CLOSE_WAIT,意味著代碼中可能沒(méi)有對(duì)連接斷開(kāi)的套接字進(jìn)行close操作。解決方案就是檢查代碼。
5. TIME_WAIT狀態(tài)有什么作用?
TIME_WAIT狀態(tài)是主動(dòng)關(guān)閉方在收到對(duì)方FIN后,進(jìn)行最后一次ACK回復(fù)后進(jìn)入的狀態(tài)。如果最后一次ACK丟失了,被動(dòng)關(guān)閉方等待沒(méi)收到ACK,則會(huì)重新發(fā)送FIN(只重傳一次),所以TIME_WAIT狀態(tài)就是等待這次可能重傳的ACK。
TIME_WAIT實(shí)際上是為了保護(hù)新建套接字不會(huì)使用剛被釋放的套接字的地址和端口,防止原先通信的數(shù)據(jù)對(duì)新連接造成的影響(本來(lái)需要發(fā)送到原先套接字的重傳FIN發(fā)送送到了新套接字的通信會(huì)話中)。
TIME_WAIT會(huì)等待兩個(gè)MSL(最大報(bào)文生存周期)時(shí)間---->最后重傳FIN和ACK的時(shí)間 X 2,確保本次通信的數(shù)據(jù)都消失在網(wǎng)絡(luò)中,不會(huì)對(duì)新的連接造成影響。
TIME_WAIT實(shí)際上更多是為了保護(hù)客戶端,客戶端通常不主動(dòng)綁定地址信息,交給系統(tǒng)分配;而服務(wù)端通信通常需要綁定相同的地址信息,重啟之后地址信息不變。
6. 一臺(tái)主機(jī)上出現(xiàn)大量TIME_WAIT鏈接,什么原因,怎么解決?
TIME_WAIT是主動(dòng)關(guān)閉方最后一次發(fā)送ACK產(chǎn)生的。
出現(xiàn)大量TIME_WAIT則是因?yàn)榇罅恐鲃?dòng)關(guān)閉套接字,常見(jiàn)于爬蟲(chóng)主機(jī)。
解決方案:將TIME_WAIT等待時(shí)間設(shè)置更短一些。
或:設(shè)置套接字選項(xiàng),開(kāi)啟地址復(fù)用,常見(jiàn)于服務(wù)端。
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
level:SOL_SOCKET
optname:SO_REUSEADDR
7. TCP的保活機(jī)制(心跳探測(cè))
默認(rèn)情況:通信雙方7200s沒(méi)有通信,則服務(wù)端每隔75s會(huì)向客戶端發(fā)送一個(gè)保活探測(cè)數(shù)據(jù)包,要求客戶端進(jìn)行回復(fù),連續(xù)9次沒(méi)有進(jìn)行回復(fù)則認(rèn)為連接斷開(kāi)。
可以設(shè)置保活時(shí)間和次數(shù)。
連接斷開(kāi)在后程序在上層的表現(xiàn):recv返回0;send會(huì)觸發(fā)SIGPIPE異常—>會(huì)導(dǎo)致進(jìn)程異常退出,可自定義SICPIPE信號(hào)的處理方式。
2.2 可靠傳輸
2.2.1 安全有序傳輸(保證數(shù)據(jù)可靠到達(dá)對(duì)端并且有序進(jìn)行交付)
面向鏈接(前提):首先確保雙方都具有數(shù)據(jù)收發(fā)能力
1. 確認(rèn)應(yīng)答機(jī)制
實(shí)現(xiàn)丟包檢測(cè)功能,接收方針對(duì)接收的每一條數(shù)據(jù)都應(yīng)該進(jìn)行確認(rèn)回復(fù)。
發(fā)送方收到確認(rèn)回復(fù)認(rèn)為傳輸成功,否則認(rèn)為數(shù)據(jù)丟包。
2. 超時(shí)重傳機(jī)制
發(fā)送方等待超時(shí)沒(méi)有得到確認(rèn)回復(fù),則會(huì)對(duì)數(shù)據(jù)包重新傳輸。超時(shí)等待時(shí)長(zhǎng)會(huì)隨著網(wǎng)絡(luò)環(huán)境的不同, 是有差異的.如果超時(shí)時(shí)間設(shè)的太長(zhǎng), 會(huì)影響整體的重傳效率;如果超時(shí)時(shí)間設(shè)的太短, 有可能會(huì)頻繁發(fā)送重復(fù)的包;
3. 協(xié)議字段中的序號(hào)(th_seq)和確認(rèn)序號(hào)(th_ack)進(jìn)行包序管理,實(shí)現(xiàn)有序交付
利用==協(xié)議字段中的序號(hào)(th_seq)和確認(rèn)序號(hào)(th_ack)==進(jìn)行包序管理,實(shí)現(xiàn)有序交付。
舉個(gè)例子感受一下序號(hào)(th_seq)和確認(rèn)序號(hào)(th_ack)的作用,下圖中seq為其實(shí)序號(hào),ack表示確認(rèn)序號(hào)。
4. 協(xié)議字段中的校驗(yàn)和校驗(yàn)數(shù)據(jù)一致性。
數(shù)據(jù)不一致則丟棄,丟棄則無(wú)針對(duì)此數(shù)據(jù)的確認(rèn)回復(fù),對(duì)方收不到確認(rèn)回復(fù)則重傳此數(shù)據(jù);也可直接發(fā)送重傳請(qǐng)求。
2.2.2 避免沒(méi)必要的丟包
丟包情況:
2.>傳輸起始或者過(guò)程中網(wǎng)絡(luò)突然變差所導(dǎo)致的大量丟包。
1. 滑動(dòng)窗口機(jī)制
依賴于協(xié)議字段中的窗口大小字段實(shí)現(xiàn),避免發(fā)送方發(fā)送數(shù)據(jù)過(guò)多,接收方來(lái)不及處理,緩沖區(qū)溢出之后所產(chǎn)生的丟包。
原理:接收方接收數(shù)據(jù)之后就會(huì)進(jìn)行確認(rèn)應(yīng)答,這時(shí)候會(huì)通過(guò)窗口大小字段告訴對(duì)方最多再給自己發(fā)送多少數(shù)據(jù)。窗口大小不能大于接收緩沖區(qū)剩余空間大小。
實(shí)現(xiàn):通信雙方都會(huì)維護(hù)一個(gè)發(fā)送窗口和接收窗口。
圖畫(huà)不動(dòng)了,參考文章:網(wǎng)絡(luò) 滑動(dòng)窗口機(jī)制,這個(gè)里面有比較圖解,過(guò)程較詳細(xì)。
相關(guān)概念:
MSS:最大數(shù)據(jù)段大小,表示一個(gè)TCP報(bào)文中數(shù)據(jù)的最大大小。相關(guān)協(xié)議:
停等協(xié)議:發(fā)送數(shù)據(jù)之后,收到確認(rèn)回復(fù)才會(huì)發(fā)送下一條。適合網(wǎng)絡(luò)環(huán)境差的場(chǎng)景。 回退n步協(xié)議:那一條數(shù)據(jù)丟失,則從丟失的數(shù)據(jù)包開(kāi)始整體重傳。 選擇重傳協(xié)議:哪條丟失重傳哪條。適用于網(wǎng)絡(luò)環(huán)境較好的場(chǎng)景。2. 擁塞窗口機(jī)制
擁塞窗口機(jī)制:解決網(wǎng)絡(luò)突然變差產(chǎn)生大量丟包的問(wèn)題。
原理:發(fā)送方維護(hù)了一個(gè)擁塞窗口,用于限制當(dāng)前所能發(fā)送的數(shù)據(jù)量。擁塞窗口大小是一種慢啟動(dòng)快增長(zhǎng)(指數(shù)上漲,閾值為窗口大小)的形式進(jìn)行傳輸控制。防止突然網(wǎng)絡(luò)變差,導(dǎo)致大量丟包。每次丟包都會(huì)進(jìn)行一次網(wǎng)絡(luò)狀況探測(cè)的過(guò)程。
2.2.3 提高一些傳輸性能
tcp為了實(shí)現(xiàn)可靠傳輸,犧牲了傳輸性能,而在傳輸過(guò)程中,有些性能上的損失是沒(méi)有必要的。
1. 確認(rèn)序號(hào)
確認(rèn)序號(hào)標(biāo)識(shí)序號(hào)之前的數(shù)據(jù)都已經(jīng)收到了,為了避免因?yàn)榇_認(rèn)應(yīng)答丟失導(dǎo)致的重傳。
2. 快速重傳協(xié)議
在傳輸過(guò)程中,若接收方接收到的數(shù)據(jù)并非是接收窗口后沿?cái)?shù)據(jù),則有理由認(rèn)為前邊發(fā)送的數(shù)據(jù)丟失了,這時(shí)候每收到一條數(shù)據(jù)就會(huì)發(fā)送一條后沿?cái)?shù)據(jù)的重傳請(qǐng)求,一旦發(fā)送方連續(xù)收到三條(三條是為了避免數(shù)據(jù)延遲到達(dá)的情況)相同重傳請(qǐng)求,則直接對(duì)這條數(shù)據(jù)(確認(rèn)序號(hào)的數(shù)據(jù))進(jìn)行重傳。丟包后不用完全等待超時(shí)重傳,節(jié)省時(shí)間。
3. 捎帶應(yīng)答機(jī)制:
接收方對(duì)接收到的每一條數(shù)據(jù)都需要進(jìn)行確認(rèn)回復(fù),然而確認(rèn)回復(fù)最主要的信息就是確認(rèn)序號(hào),因此每一條確認(rèn)回復(fù)都是一個(gè)tcp傳輸,至少是一個(gè)空?qǐng)?bào)頭(沒(méi)有實(shí)際數(shù)據(jù))的傳輸。如果收到數(shù)據(jù)后剛好要給對(duì)方發(fā)送數(shù)據(jù),則將及即將要發(fā)送的數(shù)據(jù)和確認(rèn)回復(fù)放到一起進(jìn)行發(fā)送(在要發(fā)送的數(shù)據(jù)報(bào)頭中加入確認(rèn)序號(hào))。
4. 延遲應(yīng)答機(jī)制
接收方對(duì)接收到的每一條數(shù)據(jù)都需要進(jìn)行確認(rèn)回復(fù),其中包含有當(dāng)前窗口大小字段,如果立即進(jìn)行回復(fù),窗口大概率是不斷減小的,因此延遲進(jìn)行確認(rèn)回復(fù),有可能上層將數(shù)據(jù)取出,維持窗口大小。通過(guò)這種方式保證傳輸吞吐量不會(huì)降低。
5. 延遲發(fā)送機(jī)制
tcp傳輸過(guò)程中,如果對(duì)每次send的數(shù)據(jù)直接封裝報(bào)頭進(jìn)行發(fā)送,若發(fā)送的數(shù)據(jù)比較小,但是次數(shù)較多,則io次數(shù)比較多,效率低。因此延遲發(fā)送,將數(shù)據(jù)在發(fā)送緩沖區(qū)中先堆積起來(lái),再合適的時(shí)候一次性發(fā)送,減少了io次數(shù),提高效率。
nagle算法–通過(guò)套接字選項(xiàng)設(shè)置(默認(rèn)是開(kāi)啟的)
2.3 面向字節(jié)流傳輸
面向字節(jié)流傳輸:可靠的,有序的,雙向的,基于連接的,以字節(jié)為單位的傳輸方式。傳輸時(shí),并不限制上層(send \ recv)發(fā)送或者接收的數(shù)據(jù)大小。tcp延遲發(fā)送數(shù)據(jù)在緩沖區(qū)中積攢,基于mss取出合適大小數(shù)據(jù)進(jìn)行發(fā)送。
優(yōu)勢(shì):相對(duì)于面向數(shù)據(jù)報(bào)來(lái)說(shuō),傳輸更加靈活。
缺陷:產(chǎn)生粘包問(wèn)題—將多條數(shù)據(jù)當(dāng)作一條數(shù)據(jù)處理。
產(chǎn)生粘包的原因:tcp不會(huì)對(duì)數(shù)據(jù)進(jìn)行邊界處理。
解決方案:程序員需要在應(yīng)用層進(jìn)行數(shù)據(jù)的邊界管理。可用特殊字符作為間隔(需要考慮特殊字符轉(zhuǎn)譯);使用TLV格式數(shù)據(jù)(在應(yīng)用層頭部加入數(shù)據(jù)長(zhǎng)度);數(shù)據(jù)定長(zhǎng)----提前約定會(huì)定長(zhǎng)的數(shù)據(jù),但是數(shù)據(jù)太短需要進(jìn)行補(bǔ)全;
3 對(duì)應(yīng)用層編程影響
recv一旦返回0,就要考慮文件描述符的回收關(guān)閉
Send因?yàn)闀?huì)觸發(fā)一次導(dǎo)致進(jìn)程退出,若不想退出進(jìn)程需要自定義信號(hào)處理。
問(wèn)題:tcp和udp協(xié)議的區(qū)別?
實(shí)現(xiàn)上的區(qū)別:協(xié)議格式,協(xié)議字段不一樣。
特性上的區(qū)別:TCp是面向連接的可靠的字節(jié)流傳輸方式。udp是無(wú)連接不可靠面向數(shù)據(jù)報(bào)的傳輸方式。udp支持廣播,tcp不支持。
應(yīng)用場(chǎng)景上的區(qū)別:UDP適用于實(shí)時(shí)性高于安全性的場(chǎng)景,tcp用于傳輸安全性高于實(shí)時(shí)性的場(chǎng)景。
tcp如何實(shí)現(xiàn)可靠傳輸
udp如何實(shí)現(xiàn)可靠傳輸
ud協(xié)議本身沒(méi)有實(shí)現(xiàn)可靠傳輸,需要在應(yīng)用層手動(dòng)實(shí)現(xiàn)類似tcp的可靠傳輸機(jī)制:確認(rèn)應(yīng)答機(jī)制,超時(shí)重傳機(jī)制,包序管理。
總結(jié)
以上是生活随笔為你收集整理的TCP协议格式和特点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: PUN☀️八、拓展网络同步:RPCs 和
- 下一篇: CentOS 7 配置Ruby语言开发环