一文看懂-圖解TCP/UDP

一、TCP
1、TCP首部

源端口(Source Port): 使用 TCP 協(xié)議傳輸數(shù)據(jù)的端口號(hào)
目的端口(Destination Port): 數(shù)據(jù)傳輸目的主機(jī)所對(duì)應(yīng)的端口號(hào)
序號(hào)(Sequence Number): 表示在該報(bào)文段中的數(shù)據(jù)相對(duì)于要發(fā)送的所有數(shù)據(jù)中的偏移量 (從上層傳下來的數(shù)據(jù)一般在傳輸層就已經(jīng)切分了, 這樣如果有一個(gè)報(bào)文段丟失/出錯(cuò)的話, 發(fā)送端就只需要傳輸對(duì)應(yīng)的報(bào)文段即可(TCP 差錯(cuò)控制). 若是到網(wǎng)絡(luò)層或數(shù)據(jù)鏈路層再切分, 則若出錯(cuò), 需要重新發(fā)送整個(gè)數(shù)據(jù))
確認(rèn)號(hào)(Acknowledgement Number): 表示期望對(duì)方發(fā)送過來的報(bào)文段的序號(hào)(Sequence Number)
數(shù)據(jù)偏移(Data Offset): 指數(shù)據(jù)部分在整個(gè) TCP 報(bào)文段中的偏移量(即 TCP 首部的長度)
控制位
URG(Urgent): 表示是否有緊急情況, 當(dāng)值為 1 時(shí), 從"數(shù)據(jù)偏移"開始的"緊急指針"個(gè)字節(jié)會(huì)優(yōu)先發(fā)送
ACK(Acknowledgement): 當(dāng)值為 1 時(shí), 對(duì)應(yīng)確認(rèn)號(hào)(ack)表示期望對(duì)方接下來發(fā)送過來的數(shù)據(jù)的序號(hào)(seq)
PSH(Push): 當(dāng) PSH 值為 1 時(shí), 接收到該報(bào)文段的主機(jī)會(huì)盡快將數(shù)據(jù)交付給應(yīng)用程序, 而不會(huì)等到緩存滿了之后再交付給上層
RST(Reset flag): 當(dāng)值為 1 時(shí), 表示網(wǎng)絡(luò)狀態(tài)不好, 需要釋放連接, 并重新建立連接
SYN(Synchronize flag): 當(dāng)值為 1 時(shí), 表示期望與對(duì)方建立連接
FIN(Final flag): 釋放連接
16位窗口大小(Window Size): 接收/發(fā)送窗口的大小,流量控制使用,如果窗口大小為0,可以發(fā)送窗口探測(cè)
16位校驗(yàn)和(Checksun): 校驗(yàn)和用來做差錯(cuò)控制,TCP校驗(yàn)和的計(jì)算包括TCP首部、數(shù)據(jù)和其它填充字節(jié)。在發(fā)送TCP數(shù)據(jù)段時(shí),由發(fā)送端計(jì)算校驗(yàn)和,當(dāng)?shù)竭_(dá)目的地時(shí)又進(jìn)行一次檢驗(yàn)和計(jì)算。如果兩次校驗(yàn)和一致,說明數(shù)據(jù)是正確的,否則將認(rèn)為數(shù)據(jù)被破壞,接收端將丟棄該數(shù)據(jù)
16位緊急指針:僅在URG控制位為 1 時(shí)有效。表示緊急數(shù)據(jù)的末尾在 TCP 數(shù)據(jù)部分中的位置。通常在暫時(shí)中斷通信時(shí)使用(比如輸入 Ctrl + C)
2、流量控制

流量控制,就是讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收
利用滑動(dòng)窗口機(jī)制可以很方便地在tcp連接上實(shí)現(xiàn)對(duì)發(fā)送方的流量控制
TCP接收方利用自己的接收窗口的大小來限制發(fā)送方發(fā)送窗口的大小
TCP接受方的窗口可以劃分成四個(gè)部分:1、已經(jīng)接收并且已經(jīng)確認(rèn)的TCP段;2、已經(jīng)接收但是沒有確認(rèn)的TCP段;3、還未接收但是發(fā)送方已經(jīng)發(fā)送的TCP段;4、還未接收但是發(fā)送也不允許發(fā)送的TCP段。
重傳計(jì)時(shí)器
TCP發(fā)送方收到接收方的零窗口通知后,應(yīng)啟動(dòng)持續(xù)計(jì)時(shí)器。持續(xù)計(jì)時(shí)器超時(shí)后,向接收方發(fā)送零窗口探測(cè)報(bào)文
即使接收窗口為0,接收方也會(huì)接收:零窗口探測(cè)報(bào)文段、確認(rèn)報(bào)文段、攜帶緊急數(shù)據(jù)的報(bào)文段
TCP發(fā)送方的發(fā)送窗口大小 = Math.min(自身擁塞窗口大小, TCP接收方的接收窗口大小)
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??


3、擁塞控制
什么是擁塞

假定條件
數(shù)據(jù)是單方向發(fā)送,而另一方向只傳送確認(rèn) 接收方總是有足夠大的緩存空間,因而發(fā)送方發(fā)送窗口的大小由網(wǎng)絡(luò)的擁塞程度來決定 以最大報(bào)文段MSS的個(gè)數(shù)為討論問題的單位,而不是以字節(jié)為單位
慢開始 + 擁塞避免算法
MSS:TCP最大報(bào)文段 ssthresh:慢開始門限 cwnd:擁塞窗口 swnd:發(fā)送窗口 rtt:每次往返時(shí)間

快重傳

慢開始 + 擁塞避免算法中,發(fā)送方把擁塞窗口cwnd又設(shè)置為1,并錯(cuò)誤地啟動(dòng)慢開始算法,降低了傳輸效率

收到3個(gè)重復(fù)確認(rèn)
接收方收到失序的報(bào)文段,立即發(fā)出重復(fù)確認(rèn)
發(fā)送方收到3個(gè)連續(xù)的重復(fù)確認(rèn),立即重傳

快恢復(fù)

慢開始 + 擁塞避免+快重傳 + 快恢復(fù)結(jié)合

4、TCP狀態(tài)機(jī)

CLOSED:表示初始狀態(tài)。對(duì)服務(wù)端和客戶端雙方都一樣。
LISTEN:表示監(jiān)聽狀態(tài)。服務(wù)端調(diào)用了 listen 函數(shù)使其處于監(jiān)聽狀態(tài),此時(shí)可以開始 accept (接收)客戶端的連接。
SYN_SENT:表示客戶端已經(jīng)發(fā)送了 SYN 報(bào)文段,則會(huì)處于該狀態(tài)。當(dāng)客戶端調(diào)用 connect 函數(shù)發(fā)起連接請(qǐng)求時(shí),首先發(fā) SYN 給服務(wù)端,然后自己進(jìn)入 SYN_SENT 狀態(tài),并等待服務(wù)端發(fā)送 ACK+SYN 作為請(qǐng)求應(yīng)答。
SYN_RCVD:表示服務(wù)端收到客戶端發(fā)送 SYN 報(bào)文段。服務(wù)端收到這個(gè)報(bào)文段后,進(jìn)入 SYN_RCVD 狀態(tài),然后發(fā)送 ACK+SYN 給客戶端。
ESTABLISHED:表示 TCP 連接已經(jīng)成功建立,通信雙方可以開始傳輸數(shù)據(jù)。服務(wù)端發(fā)送完 ACK+SYN 并收到來自客戶端的 ACK 后進(jìn)入該狀態(tài),客戶端收到來自服務(wù)器的 SYN+ACK 并發(fā)送 ACK 后也進(jìn)入該狀態(tài)。
FIN_WAIT_1:表示主動(dòng)關(guān)閉連接。無論哪方調(diào)用 close 函數(shù)發(fā)送 FIN 報(bào)文都會(huì)進(jìn)入這個(gè)這個(gè)狀態(tài)。
FIN_WAIT_2:表示被動(dòng)關(guān)閉方同意關(guān)閉連接。主動(dòng)關(guān)閉連接方收到被動(dòng)關(guān)閉方返回的 ACK 后,會(huì)進(jìn)入該狀態(tài)。
TIME_WAIT:表示收到對(duì)方的 FIN 報(bào)文并發(fā)送了 ACK 報(bào)文,就等 2MSL 后即可回到 CLOSED 狀態(tài)了。如果 FIN_WAIT_1 狀態(tài)下,收到對(duì)方同時(shí)帶 FIN 標(biāo)志和 ACK 標(biāo)志的報(bào)文時(shí),可以直接進(jìn)入 TIME_WAIT 狀態(tài),而無須經(jīng)過 FIN_WAIT_2 狀態(tài)。
CLOSING:表示雙方同時(shí)關(guān)閉連接。如果雙方幾乎同時(shí)調(diào)用 close 函數(shù),那么會(huì)出現(xiàn)雙方同時(shí)發(fā)送 FIN 報(bào)文的情況,就會(huì)出現(xiàn) CLOSING 狀態(tài),表示雙方都在關(guān)閉連接。
CLOSE_WAIT:表示被動(dòng)關(guān)閉方等待關(guān)閉。當(dāng)收到對(duì)方調(diào)用 close 函數(shù)發(fā)送的 FIN 報(bào)文時(shí),回應(yīng)對(duì)方 ACK 報(bào)文,此時(shí)進(jìn)入 CLOSE_WAIT 狀態(tài)。
LAST_ACK:表示被動(dòng)關(guān)閉方發(fā)送 FIN 報(bào)文后,等待對(duì)方的 ACK 報(bào)文狀態(tài),當(dāng)收到 ACK 后進(jìn)入CLOSED狀態(tài)
4.1 三次握手
發(fā)送端:SYN=1、seq=x 接收端:ACK=1、ack=x+1、SYN=1、seq=y 發(fā)送端:ACK=1、ack=y+1、seq=x+1
TCP規(guī)定:SYN被設(shè)置為1的報(bào)文段不能攜帶數(shù)據(jù),但要消耗掉一個(gè)序號(hào) TCP規(guī)定:普通的確認(rèn)報(bào)文段如果不攜帶數(shù)據(jù),則不消耗序號(hào)

4.2 四次揮手
發(fā)送端:FIN=1,ACK=1,seq=u,ack=v(u等于發(fā)送端已傳送過的數(shù)據(jù)的最后一個(gè)字節(jié)序號(hào)+1,v等于發(fā)送端之前已收到的數(shù)據(jù)的最后一字節(jié)序號(hào)+1) 接收端:ACK=1,ack=u+1,seq=v 接收端:FIN=1,ACK=1,ack=u+1,seq=w(w:半關(guān)閉情況下,可能收到了數(shù)據(jù)) 發(fā)送端:ACK=1,ack=w+1,seq=u+1
TCP規(guī)定:終止位FIN等于1的報(bào)文段,即使不攜帶數(shù)據(jù),也要一個(gè)消耗掉一個(gè)序號(hào) MSL:最長報(bào)文段壽命,建議為2分鐘
為什么要等待2MSL?
如果接收端發(fā)送FIN連接釋放,發(fā)送端接收后發(fā)送ACK,如果丟失,會(huì)導(dǎo)致接收端超時(shí)重傳,而無法進(jìn)入CLOSED狀態(tài)

4.3 ?;钣?jì)時(shí)器

4.4 半連接隊(duì)列
服務(wù)器第一次收到客戶端的 SYN 之后,就會(huì)處于 SYN_RCVD 狀態(tài),此時(shí)雙方還沒有完全建立其連接,服務(wù)器會(huì)把此種狀態(tài)下請(qǐng)求連接放在一個(gè)隊(duì)列里,我們把這種隊(duì)列稱之為半連接隊(duì)列。
4.5 三次握手能不能改成兩次握手?
不能
TCP發(fā)送連接請(qǐng)求,但長時(shí)間沒到達(dá),然后觸發(fā)了超時(shí)重傳,又發(fā)送了一次,后建立連接,數(shù)據(jù)傳輸,并斷開了連接,但此時(shí)之前沒達(dá)到的請(qǐng)求報(bào)文段突然又到了接收端服務(wù)器,接收端服務(wù)器變成了ESTABLISHED狀態(tài),接收端一直在等發(fā)送端發(fā)送數(shù)據(jù),白白浪費(fèi)了主機(jī)很多資源,導(dǎo)致了錯(cuò)誤
4.6 四次揮手能不能改成三次揮手?
不能
接收端可能還有數(shù)據(jù)沒有發(fā)送,需要等待一段時(shí)間,發(fā)送完數(shù)據(jù),才會(huì)發(fā)送FIN.
4.7 SYN攻擊
服務(wù)器端的資源分配是在二次握手時(shí)分配的,而客戶端的資源是在完成三次握手時(shí)分配的,所以服務(wù)器容易受到SYN洪泛攻擊。SYN攻擊就是Client在短時(shí)間內(nèi)偽造大量不存在的IP地址,并向Server不斷地發(fā)送SYN包,Server則回復(fù)確認(rèn)包,并等待Client確認(rèn),由于源地址不存在,因此Server需要不斷重發(fā)直至超時(shí),這些偽造的SYN包將長時(shí)間占用未連接隊(duì)列,導(dǎo)致正常的SYN請(qǐng)求因?yàn)殛?duì)列滿而被丟棄,從而引起網(wǎng)絡(luò)擁塞甚至系統(tǒng)癱瘓。SYN 攻擊是一種典型的 DoS/DDoS 攻擊。
5、tcp 怎樣保證數(shù)據(jù)正確性?
差錯(cuò)控制 發(fā)送的數(shù)據(jù)包的二進(jìn)制相加然后取反,檢測(cè)數(shù)據(jù)在傳輸過程中的任何變化,如果收到段的檢驗(yàn)和有差錯(cuò),TCP 將丟棄這個(gè)報(bào)文段和不確認(rèn)收到此報(bào)文段。編號(hào) + 排序 TCP 給發(fā)送的每一個(gè)包進(jìn)行編號(hào),接收方對(duì)數(shù)據(jù)包進(jìn)行排序,把有序數(shù)據(jù)傳送給應(yīng)用層 確認(rèn) + 超時(shí)重傳的機(jī)制 當(dāng) TCP 發(fā)出一個(gè)段后,它啟動(dòng)一個(gè)定時(shí)器,等待目的端確認(rèn)收到這個(gè)報(bào)文段。如果不能及時(shí)收到一個(gè)確認(rèn),將重發(fā)這個(gè)報(bào)文段。流量控制
TCP 連接的每一方都有固定大小的緩沖空間,TCP 的接收端只允許發(fā)送端發(fā)送接收端緩存區(qū)能接納的數(shù)據(jù)。當(dāng)接收方來不及處理發(fā)送方的數(shù)據(jù),能提示發(fā)送方降低發(fā)送的速率,防止包丟失。TCP 使用的流量控制協(xié)議是可變大小的滑動(dòng)窗口協(xié)議。
擁塞控制
當(dāng)網(wǎng)絡(luò)擁塞時(shí),減少數(shù)據(jù)的發(fā)送。發(fā)送方有擁塞窗口,發(fā)送數(shù)據(jù)前比對(duì)接收方發(fā)過來的接收窗口,取兩者的最小值---慢啟動(dòng)、擁塞避免、擁塞發(fā)送、快速恢復(fù)
二、UDP

三、TCP/UDP對(duì)比
TCP/IP協(xié)議架構(gòu)
對(duì)比
1、是否面向連接
UDP:無連接 TCP:面向連接(三次握手,四次揮手)
2、是否支持廣播和多播
UDP:支持一對(duì)一,一對(duì)多,多對(duì)一和多對(duì)多交互通信 TCP:只能一對(duì)一通信

3、對(duì)應(yīng)用層報(bào)文的處理
UDP:面向報(bào)文(對(duì)應(yīng)用層交付的報(bào)文直接打包) TCP:面向字節(jié)流(是tcp實(shí)現(xiàn)可靠傳輸,流量控制,擁塞控制的基礎(chǔ))

4、是否提供可靠傳輸
UDP:向上提供無連接不可靠服務(wù) UDP:適用于實(shí)時(shí)應(yīng)用(IP電話、視頻會(huì)議等) TCP:向上提供面向連接的可靠服務(wù) TCP:適用于要求可靠傳輸?shù)膽?yīng)用,例如文件傳輸
5、首部開銷
UDP:8個(gè)字節(jié) TCP:最小20字節(jié),最大60字節(jié)

原文作者:極客重生
