wordpress wordpress.orgseo推廣軟
文章目錄
- UDP協(xié)議
- UDP協(xié)議數(shù)據(jù)報
- 報頭
- TCP協(xié)議
- 確認(rèn)應(yīng)答
- 緩沖區(qū)
- 超時重傳
- 三次握手
- 其他問題
- 四次揮手
- 滑動窗口
- 流量控制
- 擁塞控制
UDP協(xié)議
前面我們只是說了UDP協(xié)議的用法,但是并沒有涉及到UDP協(xié)議的原理
畢竟知道冰箱的用法和知道冰箱的原理是兩個層級的事情
我們首先知道計算機網(wǎng)絡(luò)世界是搭建在四層架構(gòu)上的
而HTTP協(xié)議是處于最頂層,是應(yīng)用層協(xié)議,應(yīng)用層協(xié)議的最大特點就是非常多,而且各異
這樣多的協(xié)議要在網(wǎng)絡(luò)中傳輸,必須得給他統(tǒng)一了,并且還能將底層收上來的數(shù)據(jù),正確的交付到各個端口中
做到這些的就是傳輸層協(xié)議,主要有兩個,就是大名鼎鼎的UDP和TCP
UDP協(xié)議數(shù)據(jù)報
所有的協(xié)議都規(guī)定了兩部分,就是報頭和數(shù)據(jù)本身,在傳輸層我們一般習(xí)慣把這整體稱之為數(shù)據(jù)包
報頭
報頭是這樣的
相比于IP協(xié)議和TCP協(xié)議,UDP協(xié)議的報頭還是十分友好的
UDP的報頭大小是固定的,8字節(jié),因此當(dāng)我們獲取到一個UDP數(shù)據(jù)報之后,取前8個字節(jié),找到UDP數(shù)據(jù)報的總長度,就能完整的取到整個報文數(shù)據(jù)
需要注意的是,16位UDP長度指的是UDP數(shù)據(jù)報的總長度,包含報頭和數(shù)據(jù)部分,因此UDP的最大數(shù)據(jù)大小就是2^16-1,大小就是64KB
UDP的傳輸過程是不可靠的,無連接的,面向數(shù)據(jù)報,在我們之前介紹的時候有說過,他的主要應(yīng)用場景其實就是直播了
TCP協(xié)議
TCP報頭就比UDP丑多了,而且他還是不定長的,其中有一個交4位首部長度,是代表了TCP報頭的大小,范圍是20到60字節(jié)
其他的部分都是用來確保TCP的可靠性和效率所用到的
TCP如此知名,就是因為他的可靠性,那么他做了哪些事情保證他的可靠呢
確認(rèn)應(yīng)答
我們發(fā)出了一條信息,怎么確定對方是否看到了呢,在Line或者抖音中,會回顯對方是否已讀,這其實就是一個確認(rèn)應(yīng)答機制
為了保證可靠性,TCP協(xié)議規(guī)定了ACK機制,也就是確認(rèn)應(yīng)答機制
機智的朋友肯定發(fā)現(xiàn)上面的標(biāo)志位中有一個ACK,就是用于這個事情的
但是如果服務(wù)器和客戶機一人一條發(fā)送,服務(wù)器每發(fā)送一個數(shù)據(jù),都要等客戶端回答收到之后再發(fā)送,這樣固然是可靠了,但是效率卻也大大降低了
于是就有了下面的想法,一次發(fā)送10條數(shù)據(jù),分別標(biāo)記上1到10
客戶端收到1回復(fù)2,表明自己的1收到了,下一個想要2,因此客戶端在一次收到1到10之后會分別回復(fù)2到11
但是計算機網(wǎng)絡(luò)紛繁復(fù)雜,數(shù)據(jù)報可不一定是按順序到達的,這就麻煩了,我怎么知道我缺哪個呢,而且每一個都進行回復(fù)也太二了
然后我們再想,一次發(fā)送了1到10,但是接收到了,1到5,8到10,6和7都丟了
那我們只回復(fù)5,標(biāo)識5以前的都正確收到了,接下來想要6
這樣就好很多了
緩沖區(qū)
除此之外,TCP的協(xié)議是全雙工的,用一個端口就可以執(zhí)行發(fā)送和接收兩個操作,而且系統(tǒng)調(diào)用recv和read也不是從網(wǎng)卡中讀取數(shù)據(jù)到內(nèi)存,而是從緩沖區(qū)里拿上來的,send和write其實也算寫入到緩沖區(qū)的,不是直接寫到網(wǎng)卡里
那這個緩沖區(qū)寫滿了怎么辦,怎么知道,發(fā)送緩沖區(qū)沒數(shù)據(jù)了怎么辦
這其實就是那16位的窗口做的事情,他分別對應(yīng)了緩沖區(qū)的大小,每一次收發(fā)其實都會把緩沖區(qū)的狀態(tài)寫在里面,當(dāng)緩沖區(qū)都快滿了,寫方就知道不要再往里面?zhèn)髁?/p>
超時重傳
當(dāng)數(shù)據(jù)在傳輸過程中丟了怎么辦,遲遲沒有收到ACK就說明發(fā)送失敗了
當(dāng)服務(wù)器等了一段時間也沒有收到客戶機發(fā)來的ACK,就說明數(shù)據(jù)可能是丟了,無論是數(shù)據(jù)丟了,還是ACK丟了,都會觸發(fā)超時重傳
這時候TCP協(xié)議就會要求服務(wù)器重新傳一次數(shù)據(jù)
一般來說這個一段時間其實是動態(tài)的,各家操作系統(tǒng)都是這樣
邏輯是這樣的500ms是一個單位,每次乘2,當(dāng)次數(shù)有幾次之后,就說明對方主機可能出毛病了,有可能是被拔網(wǎng)線了,這時候就不會重傳了
其實TCP協(xié)議他可靠嗎,確實,在他能做到的范圍內(nèi)確實可靠,但是如果被拔網(wǎng)線就沒辦法了(不可抗力)
三次握手
我們說TCP協(xié)議是面向連接的,這個連接是怎么建立的呢
就是通過三次握手,在TCP報頭中的SYN標(biāo)記就是標(biāo)識我要跟你交朋友
過程是這樣的
客戶端發(fā)起請求,說,我要跟你做朋友(發(fā)送一個包含SYN標(biāo)記的報文)
服務(wù)端收到之后,說,我收到了你的消息,我也要跟你做朋友(發(fā)送了一個ACK和SYN標(biāo)記都有的報文)
客戶端收到之后,說,好!(發(fā)送一個ACK標(biāo)記的報文)
這三次數(shù)據(jù)傳遞其實就建立了一個TCP連接,但是建立連接的時候,是在哪一個動作呢
其實是在客戶端最后一次發(fā)送之后,客戶端就認(rèn)為連接建立好了,而服務(wù)器接收到了之后,服務(wù)器就認(rèn)為連接建立好了
接下來客戶端就可以發(fā)送請求了,瘋狂星期四,V我50
需要注意的是,服務(wù)器可不是一次只跟一個客戶機聊天,說不定有成千上萬的客戶端來請求,而操作系統(tǒng)的管理策略其實就是先描述再組織,將這些連接管理起來
其他問題
有一個經(jīng)典的面試問題為什么是三次握手,其他次數(shù)行不行
- 偶數(shù)次
這里需要知道一點,當(dāng)我發(fā)出一條消息的時候,我是不知道這條消息能不能傳達到的,但是可以確定的是,我之前的消息一定傳到了,并且我也可以收到對方的消息
而在這個過程中,永遠(yuǎn)是客戶機給服務(wù)器發(fā)送請求,如果是奇數(shù)次,說明最后一個確認(rèn)是服務(wù)器發(fā)給客戶端的,說明之前的信息都沒問題了,為什么還要繼續(xù)確認(rèn)呢?我直接發(fā)我的請求不好嗎
而且如果使用偶數(shù)次握手,是服務(wù)器先確認(rèn)建立的連接,客戶端就可以一直發(fā)送SYN報文,一直不建立連接,服務(wù)器需要面對的可就多了,維護連接過多可是會掛掉的
- 其他奇數(shù)次呢
1次就不說了太蠢了,5次以上那不就是浪費資源了
3次就能干好的事情為什么要5次7次,那不是脫褲子放屁嗎
四次揮手
有資源的申請就要有資源的釋放,有鏈接的申請就要有鏈接的釋放
在TCP報頭中有一個叫做FIN,其實就是final,標(biāo)志著我要離開我的朋友了
鏈接的釋放可以說客戶端也可以是服務(wù)器,這里我為了方便表示說是客戶端,表示我要的資源已經(jīng)拿到了,要拜拜了
客戶端發(fā)出請求,要拜拜了(發(fā)送一個帶有FIN的報文)
服務(wù)器收到了,我知道了(原地等待一會兒)(返回一個ACK,表示我知道了,然后等待一個CLOSE_WAIT的時間,給客戶機反悔的機會,看客戶機還有沒有別的話說)
這段時間服務(wù)器什么也沒有等到,服務(wù)器說,這是我跟你說的最后一句話,以后再也沒有了(假),拜拜(發(fā)送了一個LAST_ACK,表示最后一個ACK報文,并且附帶了FIN標(biāo)志,表示結(jié)束)
當(dāng)客戶端收到之后,其實連接就已經(jīng)斷開了,并且會維持一段時間TIME_WAIT,不讓客戶端對同一個端口發(fā)送請求,咱不能抓著一只羊薅羊毛吧
滑動窗口
如果服務(wù)器發(fā)送了1到20號數(shù)據(jù),但是客戶端收到的是1和3到20,只發(fā)了一個2的請求,服務(wù)器看到之后覺得他只收到了1,于是把2到20又發(fā)了一遍,這樣的效率又變得不行了
于是就有了滑動窗口,我們把發(fā)送緩沖區(qū)和接收緩沖區(qū)想象成數(shù)組,兒窗口限制的其實是左右的下標(biāo),我們每次只確認(rèn)窗口中的數(shù)據(jù)即可
需要注意的是,在滑動窗口中的每一個部分其實都是需要確認(rèn)ACK的,這是和之前不一樣的
流量控制
流量控制其實用到的原理就是上面的滑動窗口,我們需要控制發(fā)送數(shù)據(jù)的速度,不能讓接收端的緩沖區(qū)過滿,不然就是無用功了
這時候TCP報頭中的顯示緩沖區(qū)情況就起到作用了
擁塞控制
擁塞控制與流量控制不同,他是為了防止網(wǎng)絡(luò)狀況不好產(chǎn)生的原因,比如說路由器出問題,網(wǎng)絡(luò)擁堵送不出去
TCP的解決方案是慢啟動,他指的是一開始的發(fā)送的數(shù)據(jù)很少,但是是指數(shù)級別的增長
當(dāng)這個增長達到一定閾值之后,就是用線性增長了,如果遇到了重傳,就會減半