Java常見面試題匯總-----------計算機網(wǎng)絡(luò)(TCP三次握手與四次揮手、TCP流量控制、TCP與UDP對比)

70、TCP協(xié)議的三次握手與四次揮手

70.1、TCP報文結(jié)構(gòu)

??1、源端口號:表示發(fā)送端端口號,字段長為16位。
??2、目標(biāo)端口號:表示接收端口號,字段長為16位。
??3、序列號:表示發(fā)送數(shù)據(jù)的位置,字段長為32位。每發(fā)送一次數(shù)據(jù),就累加一次該數(shù)據(jù)字節(jié)數(shù)的大小。
??注意:序列號不會從0或1開始,而是在建立連接時由計算機生成的一個隨機數(shù)作為其初始值,通過SYN包發(fā)送給接收端主機。然后再將每次轉(zhuǎn)發(fā)過去的字節(jié)數(shù)累加到初始值上表示數(shù)據(jù)的位置。
??4、確認應(yīng)答號:表示下一次應(yīng)該收到的數(shù)據(jù)的序列號,字段長為32字節(jié)。發(fā)送端收到這個確認應(yīng)答以后可以認為在這個序號以前的數(shù)據(jù)都已經(jīng)被正常接收。
??序號的優(yōu)點:
??(1)保證報文按序到達。
??(2)保證可靠性。
??(3)保證效率。
??(4)精準(zhǔn)的報告哪些報文已經(jīng)收到,哪些需要重傳。
??5、首部長度:該字段長度為4位,單位為4字節(jié)(32位)。TCP首部長度不包括選項的話,是20個字節(jié),20/4=5,5的二進制序列:0101,報頭長度也叫數(shù)據(jù)偏移,所以該字段可以設(shè)置為5,選項字段最大的是40字節(jié),所以,TCP首部長度為最大為20+40=60字節(jié),該字段可以設(shè)置的最大長度為60/4=15。
??6、保留:該字段主要是為了以后擴展時使用,其長度為4位。一般設(shè)置為0,即使收到的包在該字段不為0,此包也不會丟棄。
??7、控制位:字段長為6,每一位從左到右分別為:URG、ACK、PSH、RST、SYN、FIN。當(dāng)對應(yīng)的值為1,表示有具體含義。

字段 含義
URG 緊急指針是否有效。為1,表示某一位需要被優(yōu)先處理。
ACK 確認號是否有效,一般置為1。
PSH 提示接收端應(yīng)用程序立即從TCP緩沖區(qū)把數(shù)據(jù)讀走。
RST 對方要求重新建立連接,復(fù)位。
SYN 請求建立連接,并在其序列號的字段進行序列號的初始值設(shè)定。建立連接,設(shè)置為1。
FIN 希望斷開連接。

??8、窗口大?。航邮站彌_區(qū)的大小,TCP不允許發(fā)送超過此處所示大小的數(shù)據(jù)。
??9、校驗和:發(fā)送端填充,CRC校驗,接收校驗不通過,則認為數(shù)據(jù)有問題。和UDP的區(qū)別是,UDP校驗的是數(shù)據(jù)本身,TCP校驗的不僅包含TCP首部,而且包含TCP數(shù)據(jù)部分。
??10、緊急指針:只有在URG為1時有效,該字段為1表示本報文的段中的緊急數(shù)據(jù)的指針。
??11、選項:用于提高TCP的傳輸性能。需要根據(jù)首部長度進行控制,其最大長度為40字節(jié)。

70.2、TCP三次握手以及四次揮手用到的字段

??1、序列號seq
??占4個字節(jié),用來標(biāo)記數(shù)據(jù)段的順序,TCP把連接中發(fā)送的所有數(shù)據(jù)字節(jié)都編上一個序號,第一個字節(jié)的編號由本地隨機產(chǎn)生,給字節(jié)編上序號后,就給每一個報文段指派一個序號,序列號seq就是這個報文段中的第一個字節(jié)的數(shù)據(jù)編號。
??2、確認號ack
??占4個字節(jié),期待收到對方下一個報文段的第一個數(shù)據(jù)字節(jié)的序號,序列號表示報文段攜帶數(shù)據(jù)的第一個字節(jié)的編號,而確認號指的是期望接受到下一個字節(jié)的編號,因此當(dāng)前報文段最后一個字節(jié)的編號+1即是確認號。
??3、確認ACK
??占1個比特位,僅當(dāng)ACK=1,確認號字段才有效。ACK=0,確認號無效。
??4、同步SYN
??連接建立時用于同步序號。當(dāng)SYN=1,ACK=0表示:這是一個連接請求報文段。若同意連接,則在響應(yīng)報文段中使用SYN=1,ACK=1。因此,SYN=1表示這是一個連接請求,或連接接收報文,SYN這個標(biāo)志位只有在TCP建立連接才會被置為1,握手完成后SYN標(biāo)志位被置為0。
??5、終止FIN
??用來釋放一個連接。

70.3、TCP三次握手

??step1:第一次握手
??建立連接時,客戶端發(fā)送SYN包到服務(wù)器,其中包含客戶端的初始序號seq=x,并進入SYN_SENT狀態(tài),等待服務(wù)器確認。(其中,SYN=1,ACK=0,表示這是一個TCP連接請求數(shù)據(jù)報文;序號seq=x,表明傳輸數(shù)據(jù)時的第一個數(shù)據(jù)字節(jié)的序號是x)。
??step2:第二次握手
??服務(wù)器收到請求后,必須確認客戶的數(shù)據(jù)包。同時自己也發(fā)送一個SYN包,即SYN+ACK包,此時服務(wù)器進入SYN_RECV狀態(tài)。(其中確認報文段中,標(biāo)識位SYN=1,ACK=1,表示這是一個TCP連接響應(yīng)數(shù)據(jù)報文,并含服務(wù)端的初始序號seq(服務(wù)器)=y,以及服務(wù)器對客戶端初始序號的確認號ack(服務(wù)器)=seq(客戶端)+1=x+1)。
??step3:第三次握手
??客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送一個序列號(seq=x+1),確認號為ack(客戶端)=y+1,此包發(fā)送完畢,客戶端和服務(wù)器進入ESTAB_LISHED(TCP連接成功)狀態(tài),完成三次握手。
??未連接隊列
??在三次握手協(xié)議中,服務(wù)器維護一個未連接隊列,該隊列為每個客戶端的SYN包(syn=j)開設(shè)一個條目,該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認,正在等待客戶的確認包時,刪除該條目,服務(wù)器進入ESTAB_LISHED狀態(tài)。

70.4、四次揮手過程(關(guān)閉客戶端到服務(wù)器的連接)

??step1:第一次揮手
??首先,客戶端發(fā)送一個FIN,用來關(guān)閉客戶端到服務(wù)器的數(shù)據(jù)傳送,然后等待服務(wù)器的確認。其中終止標(biāo)志位FIN=1,序列號seq=u。
??step2:第二次揮手
??服務(wù)器收到這個FIN,它發(fā)送一個ACK,確認ack為收到的序號加一。
??step3:第三次揮手
??關(guān)閉服務(wù)器到客戶端的連接,發(fā)送一個FIN給客戶端。
??step4:第四次揮手
??客戶端收到FIN后,并發(fā)回一個ACK報文確認,并將確認序號seq設(shè)置為收到序號加一。首先進行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方執(zhí)行被動關(guān)閉。
??客戶端發(fā)送FIN后,進入終止等待狀態(tài),服務(wù)器收到客戶端連接釋放報文段后,就立即給客戶端發(fā)送確認,服務(wù)器就進入CLOSE_WAIT狀態(tài),此時TCP服務(wù)器進程就通知高層應(yīng)用進程,因而從客戶端到服務(wù)器的連接就釋放了。此時是“半關(guān)閉狀態(tài)”,即客戶端不可以發(fā)送給服務(wù)器,服務(wù)器可以發(fā)送給客戶端。
??此時,如果服務(wù)器沒有數(shù)據(jù)報發(fā)送給客戶端,其應(yīng)用程序就通知TCP釋放連接,然后發(fā)送給客戶端連接釋放數(shù)據(jù)報,并等待確認。客戶端發(fā)送確認后,進入TIME_WAIT狀態(tài),但是此時TCP連接還沒有釋放,然后經(jīng)過等待計時器設(shè)置的2MSL(2倍報文最大生存時間)后,才進入到CLOSE狀態(tài)。
??【注意】中斷連接端可以是 Client 端,也可以是 Server 端。
??假設(shè) Client 端發(fā)起中斷連接請求,也就是發(fā)送 FIN 報文。Server 端接到 FIN 報文后,意思是說"我 Client 端沒有數(shù)據(jù)要發(fā)給你了",但是如果你還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉 Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。所以你先發(fā)送 ACK,"告訴 Client 端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息"。這個時候 Client 端就進入FIN_WAIT 狀態(tài),繼續(xù)等待 Server 端的 FIN 報文。當(dāng) Server 端確定數(shù)據(jù)已發(fā)送完成,則向 Client 端發(fā)送 FIN 報文,"告訴 Client 端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了"。Client 端收到 FIN 報文后,“就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕 Server 端不知道要關(guān)閉,所以發(fā)送 ACK 后進入 TIME_WAIT 狀態(tài),如果 Server端沒有收到 ACK 則可以重傳?!盨erver 端收到 ACK 后,"就知道可以斷開連接了"。Client端等待了 2MSL 后依然沒有收到回復(fù),則證明 Server 端已正常關(guān)閉,那好,我 Client 端也可以關(guān)閉連接了。Ok,TCP連接就這樣關(guān)閉了!

70.5、為什么需要三次握手,兩次不可以嗎?或者四次、五次可以嗎?

??我們來分析一種特殊情況,假設(shè)客戶端請求建立連接,發(fā)給服務(wù)器SYN包等待服務(wù)器確認,服務(wù)器收到確認后,如果是兩次握手,假設(shè)服務(wù)器給客戶端在第二次握手時發(fā)送數(shù)據(jù),數(shù)據(jù)從服務(wù)器發(fā)出,服務(wù)器認為連接已經(jīng)建立,但在發(fā)送數(shù)據(jù)的過程中數(shù)據(jù)丟失,客戶端認為連接沒有建立,會進行重傳。假設(shè)每次發(fā)送的數(shù)據(jù)一直在丟失,客戶端一直SYN,服務(wù)器就會產(chǎn)生多個無效連接,占用資源,這個時候服務(wù)器可能會掛掉。這個現(xiàn)象就是我們聽過的“SYN的洪水攻擊”。
??總結(jié):第三次握手是為了防止:如果客戶端遲遲沒有收到服務(wù)器返回確認報文,這時會放棄連接,重新啟動一條連接請求,但問題是:服務(wù)器不知道客戶端沒有收到,所以他會收到兩個連接,浪費連接開銷。如果每次都是這樣,就會浪費多個連接開銷。
??也是為了防止失效的連接請求報文段突然又傳送到服務(wù)器,因而產(chǎn)生錯誤。

70.6、為什么是四次揮手,而不是三次或是五次、六次?

??確保數(shù)據(jù)能夠完成傳輸。
??關(guān)閉連接時,當(dāng)收到對方的 FIN 報文通知時,它僅僅表示對方?jīng)]有數(shù)據(jù)發(fā)送給你了;但未必你所有的數(shù)據(jù)都全部發(fā)送給對方了,所以你可以未必會馬上會關(guān)閉 SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對方之后,再發(fā)送 FIN 報文給對方來表示你同意現(xiàn)在可以關(guān)閉連接了,所以它這里的 ACK 報文和FIN 報文多數(shù)情況下都是分開發(fā)送的。
??TCP 協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的運輸層通信協(xié)議。TCP 是全雙工模式,這就意味著,當(dāng)主機 1 發(fā)出 FIN 報文段時,只是表示主機 1 已經(jīng)沒有數(shù)據(jù)要發(fā)送了,主機 1 告訴主機 2,它的數(shù)據(jù)已經(jīng)全部發(fā)送完畢了;但是,這個時候主機 1 還是可以接受來自主機 2 的數(shù)據(jù);當(dāng)主機 2 返回 ACK 報文段時,表示它已經(jīng)知道主機 1 沒有數(shù)據(jù)發(fā)送了,但是主機 2 還是可以發(fā)送數(shù)據(jù)到主機 1 的;當(dāng)主機 2 也發(fā)送了 FIN 報文段時,這個時候就表示主機 2 也沒有數(shù)據(jù)要發(fā)送了,就會告訴主機 1,我也沒有數(shù)據(jù)要發(fā)送了,之后彼此就會愉快的中斷這次 TCP 連接。

70.7、time_wait 狀態(tài)產(chǎn)生的原因?

??1)、可靠地實現(xiàn) TCP 全雙工連接的終止
??我們必須要假想網(wǎng)絡(luò)是不可靠的,你無法保證你最后發(fā)送的 ACK 報文會一定被對方收到,因此對方處于 LAST_ACK 狀態(tài)下的 SOCKET 可能會因為超時未收到 ACK 報文,而重發(fā) FIN報文,client 必須維護這條連接的狀態(tài)(保持 time_wait,具體而言,就是這條TCP 連接對應(yīng)的(local_ip, local_port)資源不能被立即釋放或重新分配)以便可以重發(fā)丟失的 ACK,如果主動關(guān)閉端不維持 TIME_WAIT 狀態(tài),而是處于 CLOSED 狀態(tài),主動關(guān)閉端將會響應(yīng)一個 RST,結(jié)果 server 認為發(fā)生錯誤,導(dǎo)致服務(wù)器端不能正常關(guān)閉連接。所以這個TIME_WAIT 狀態(tài)的作用就是用來重發(fā)可能丟失的 ACK 報文。所以,當(dāng)客戶端等待 2MSL(2倍報文最大生存時間)后,沒有收到服務(wù)端的 FIN 報文后,他就知道服務(wù)端已收到了 ACK報文,所以客戶端此時才關(guān)閉自己的連接。
??2)、允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝
??2MSL可以使本連接持續(xù)的時間內(nèi)所有所產(chǎn)生的報文段都從網(wǎng)絡(luò)中消失。這樣就可以使下一個新的連接中不會出現(xiàn)舊的連接的請求報文段。
??如果 TIME_WAIT 狀態(tài)保持時間不足夠長 (比如小于2MSL),第一個連接就正常終止了。第二個擁有相同四元組(local_ip, local_port, remote_ip,remote_port)的連接出現(xiàn)(建立起一個相同的 IP 地址和端口之間的 TCP 連接),而第一個連接的重復(fù)報文到達,干擾了第二個連接。TCP 實現(xiàn)必須防止某個連接的重復(fù)報文在連接終止后出現(xiàn),所以讓TIME_WAIT 狀態(tài)保持時間足夠長 (2MSL),連接相應(yīng)方向上的 TCP 報文要么完全響應(yīng)完畢,要么被丟棄。建立第二個連接的時候,不會混淆。

70.8、如果網(wǎng)絡(luò)連接中出現(xiàn)大量 TIME_WAIT 狀態(tài)所帶來的危害?

??如果系統(tǒng)中有很多 socket 處于 TIME_WAIT 狀態(tài),當(dāng)需要創(chuàng)建新的 socket 連接的時候可能會受到影響,這也會影響到系統(tǒng)的擴展性。
??之所以 TIME_WAIT 能夠影響系統(tǒng)的擴展性是因為在一個 TCP 連接中,一個 Socket如果關(guān)閉的話,它將保持 TIME_WAIT 狀態(tài)大約 1-4分鐘。如果很多連接快速的打開和關(guān)閉的話,系統(tǒng)中處于 TIME_WAIT 狀態(tài)的 socket 將會積累很多,由于本地端口數(shù)量的限制,同一時間只有有限數(shù)量的 socket 連接可以建立,如果太多的socket 處于TIME_WAIT狀態(tài),你會發(fā)現(xiàn),由于用于新建連接的本地端口太缺乏,將會很難再建立新的對外連接。

70.9、TCP如何保證傳輸?shù)目煽啃裕?/h3>

??0、在傳遞數(shù)據(jù)之前,會有三次握手來建立連接。
??1、應(yīng)用數(shù)據(jù)被分割成 TCP 認為最適合發(fā)送的數(shù)據(jù)塊(按字節(jié)編號,合理分片)。這和UDP完全不同,應(yīng)用程序產(chǎn)生的數(shù)據(jù)報長度將保持不變。(將數(shù)據(jù)截斷為合理的長度)
??2、當(dāng) TCP 發(fā)出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發(fā)這個報文段。(超時重發(fā))
??3、當(dāng) TCP 收到發(fā)自 TCP 連接另一端的數(shù)據(jù),它將發(fā)送一個確認。這個確認不是立即發(fā)送,通常將推遲幾分之一秒 。(對于收到的請求,給出確認響應(yīng)) (之所以推遲,可能是要對包做完整校驗)。
??4、TCP 將保持它首部和數(shù)據(jù)的檢驗和。這是一個端到端的檢驗和,目的是檢測數(shù)據(jù)在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP 將丟棄這個報文段和不確認收到此報文段。(校驗出包有錯,丟棄報文段,不給出響應(yīng),TCP 發(fā)送數(shù)據(jù)端,超時時會重發(fā)數(shù)據(jù))
??5、既然 TCP 報文段作為 IP 數(shù)據(jù)報來傳輸,而 IP 數(shù)據(jù)報的到達可能會失序,因此TCP 報文段的到達也可能會失序。如果必要,TCP 將對收到的數(shù)據(jù)進行重新排序,將收到的數(shù)據(jù)以正確的順序交給應(yīng)用層。(對失序數(shù)據(jù)進行重新排序,然后才交給應(yīng)用層)
??6、既然 IP 數(shù)據(jù)報會發(fā)生重復(fù),TCP 的接收端必須丟棄重復(fù)的數(shù)據(jù)。(對于重復(fù)數(shù)據(jù),能夠丟棄重復(fù)數(shù)據(jù))
??7、TCP 還能提供流量控制。TCP 連接的每一方都有固定大小的緩沖空間。TCP 的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機致使較慢主機的緩沖區(qū)溢出。(TCP 可以進行流量控制,防止較快主機致使較慢主機的緩沖區(qū)溢出) TCP 使用的流量控制協(xié)議是可變大小的滑動窗口協(xié)議。
??8、TCP 還能提供擁塞控制。當(dāng)網(wǎng)絡(luò)擁塞時,減少數(shù)據(jù)的發(fā)送。

70.10、TCP 建立連接之后怎么保持連接(檢測連接斷沒斷)?

??有兩種技術(shù)可以運用。一種是由 TCP 協(xié)議層實現(xiàn)的 Keepalive 機制,另一種是由應(yīng)用層自己實現(xiàn)的 HeartBeat 心跳包。
??1、在 TCP 中有一個 Keep-alive 的機制可以檢測死連接,原理很簡單,當(dāng)連接閑置一定的時間(參數(shù)值可以設(shè)置,默認是 2 小時)之后,TCP 協(xié)議會向?qū)Ψ桨l(fā)一個 keepalive探針包(包內(nèi)沒有數(shù)據(jù)),對方在收到包以后,如果連接一切正常,應(yīng)該回復(fù)一個 ACK;如果連接出現(xiàn)錯誤了(例如對方重啟了,連接狀態(tài)丟失),則應(yīng)當(dāng)回復(fù)一個 RST;如果對方?jīng)]有回復(fù),那么,服務(wù)器每隔一定的時間(參數(shù)值可以設(shè)置)再發(fā)送 keepalive 探針包,如果連續(xù)多個包(參數(shù)值可以設(shè)置)都被無視了,說明連接被斷開了。
??2、心跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發(fā)一次,以此來告訴服務(wù)器,這個客戶端還活著。事實上這是為了保持長連接,至于這個包的內(nèi)容,是沒有什么特別規(guī)定的,不過一般都是很小的包,或者只包含包頭的一個空包。由應(yīng)用程序自己發(fā)送心跳包來檢測連接的健康性??蛻舳丝梢栽谝粋€ Timer 中或低級別的線程中定時向服務(wù)器發(fā)送一個短小精悍的包,并等待服務(wù)器的回應(yīng)??蛻舳顺绦蛟谝欢〞r間內(nèi)沒有收到服務(wù)器回應(yīng)即認為連接不可用,同樣,服務(wù)器在一定時間內(nèi)沒有收到客戶端的心跳包則認為客戶端已經(jīng)掉線。??



71、TCP流量控制(滑動窗口機制)

??滑動窗口協(xié)議的基本原理就是在任意時刻,發(fā)送方都維持了一個連續(xù)的允許發(fā)送的幀的序號,稱為發(fā)送窗口;同時,接收方也維持了一個連續(xù)的允許接收的幀的序號,稱為接收窗口。發(fā)送窗口和接收窗口的序號的上下界不一定要一樣,甚至大小也可以不同。不同的滑動窗口協(xié)議窗口大小一般不同。
??所謂滑動窗口協(xié)議,自己理解有兩點:1)、“窗口”對應(yīng)的是一段可以被發(fā)送者發(fā)送的字節(jié)序列,其連續(xù)的范圍稱之為“窗口”;2)、“滑動”則是指這段“允許發(fā)送的范圍”是可以隨著發(fā)送的過程而變化的,方式就是按順序“滑動”。在此之前要先了解以下前提:
??1、TCP 協(xié)議的兩端分別為發(fā)送者 A 和接收者 B,由于是全雙工協(xié)議,因此 A 和 B 應(yīng)該分別維護著一個獨立的發(fā)送緩沖區(qū)和接收緩沖區(qū),由于對等性(A發(fā)B收 和 B發(fā)A收),我們以 A 發(fā)送 B 接收的情況作為例子;
??2、發(fā)送窗口是發(fā)送緩存中的一部分,是可以被 TCP 協(xié)議發(fā)送的那部分,其實應(yīng)用層需要發(fā)送的所有數(shù)據(jù)都被放進了發(fā)送者的發(fā)送緩沖區(qū);
??3、發(fā)送窗口中相關(guān)的有四個概念:已發(fā)送并收到確認的數(shù)據(jù)(不在發(fā)送窗口和發(fā)送緩沖區(qū)之內(nèi))、已發(fā)送但未收到確認的數(shù)據(jù)(位于發(fā)送窗口之中)、允許發(fā)送但尚未發(fā)送的數(shù)據(jù)以及發(fā)送窗口外發(fā)送緩沖區(qū)內(nèi)暫時不允許發(fā)送的數(shù)據(jù);
??4、每次成功發(fā)送數(shù)據(jù)之后,發(fā)送窗口就會在發(fā)送緩沖區(qū)中按順序移動,將新的數(shù)據(jù)包含到窗口中準(zhǔn)備發(fā)送;

71.1、流量控制

??流量控制方面主要有兩個要點需要掌握。一是TCP利用滑動窗口實現(xiàn)流量控制的機制;二是如何考慮流量控制中的傳輸效率。
??1、流量控制
??所謂流量控制,主要是接收方傳遞信息給發(fā)送方,使其不要發(fā)送數(shù)據(jù)太快,是一種端到端的控制。主要的方式就是返回的ACK中會包含自己的接收窗口的大小,并且利用大小來控制發(fā)送方的數(shù)據(jù)發(fā)送:


??這里面涉及到一種情況,如果B已經(jīng)告訴A自己的緩沖區(qū)已滿,于是A停止發(fā)送數(shù)據(jù);等待一段時間后,B的緩沖區(qū)出現(xiàn)了富余,于是給A發(fā)送報文告訴A我的rwnd大小為400,但是這個報文不幸丟失了,于是就出現(xiàn)A等待B的通知||B等待A發(fā)送數(shù)據(jù)的死鎖狀態(tài)。為了處理這種問題,TCP引入了持續(xù)計時器(Persistence timer),當(dāng)A收到對方的零窗口通知時,就啟用該計時器,時間到則發(fā)送一個1字節(jié)的探測報文,對方會在此時回應(yīng)自身的接收窗口大小,如果結(jié)果仍為0,則重設(shè)持續(xù)計時器,繼續(xù)等待。
??2、傳遞效率
??一個顯而易見的問題是:單個發(fā)送字節(jié)單個確認,和窗口有一個空余即通知發(fā)送方發(fā)送一個字節(jié),無疑增加了網(wǎng)絡(luò)中的許多不必要的報文(請想想為了一個字節(jié)數(shù)據(jù)而添加的40字節(jié)頭部吧!),所以我們的原則是盡可能一次多發(fā)送幾個字節(jié),或者窗口空余較多的時候通知發(fā)送方一次發(fā)送多個字節(jié)。對于前者我們廣泛使用Nagle算法,即:
??1)、若發(fā)送應(yīng)用進程要把發(fā)送的數(shù)據(jù)逐個字節(jié)地送到TCP的發(fā)送緩存,則發(fā)送方就把第一個數(shù)據(jù)字節(jié)先發(fā)送出去,把后面的字節(jié)先緩存起來;
??2)、當(dāng)發(fā)送方收到第一個字節(jié)的確認后(也得到了網(wǎng)絡(luò)情況和對方的接收窗口大?。?,再把緩沖區(qū)的剩余字節(jié)組成合適大小的報文發(fā)送出去;
??3)、當(dāng)?shù)竭_的數(shù)據(jù)已達到發(fā)送窗口大小的一半或已達到報文段的最大長度時,就立即發(fā)送一個報文段;
??對于后者我們往往的做法是讓接收方等待一段時間,或者接收方獲得足夠的空間容納一個報文段或者等到接受緩存有一半空閑的時候,再通知發(fā)送方發(fā)送數(shù)據(jù)。

71.2、擁塞控制

??網(wǎng)絡(luò)中的鏈路容量和交換結(jié)點中的緩存和處理機都有著工作的極限,當(dāng)網(wǎng)絡(luò)的需求超過它們的工作極限時,就出現(xiàn)了擁塞。擁塞控制就是防止過多的數(shù)據(jù)注入到網(wǎng)絡(luò)中,這樣可以使網(wǎng)絡(luò)中的路由器或鏈路不致過載。常用的方法就是:
??1、慢開始、擁塞控制;
??2、快重傳、快恢復(fù);
??一切的基礎(chǔ)還是慢開始,這種方法的思路是這樣的:
??1)、發(fā)送方維持一個叫做“擁塞窗口”的變量,該變量和接收端口共同決定了發(fā)送者的發(fā)送窗口;
??2)、當(dāng)主機開始發(fā)送數(shù)據(jù)時,避免一下子將大量字節(jié)注入到網(wǎng)絡(luò),造成或者增加擁塞,選擇發(fā)送一個1字節(jié)的試探報文;
??3)、當(dāng)收到第一個字節(jié)的數(shù)據(jù)的確認后,就發(fā)送2個字節(jié)的報文;
??4)、若再次收到2個字節(jié)的確認,則發(fā)送4個字節(jié),依次遞增2的指數(shù)級;
??5)、最后會達到一個提前預(yù)設(shè)的“慢開始門限”,比如24,即一次發(fā)送了24個分組,此時遵循下面的條件判定:
??*1、cwnd < ssthresh,繼續(xù)使用慢開始算法;
??*2、cwnd > ssthresh,停止使用慢開始算法,改用擁塞避免算法;
??*3、cwnd = ssthresh,既可以使用慢開始算法,也可以使用擁塞避免算法;
??6)、所謂擁塞避免算法就是:每經(jīng)過一個往返時間RTT就把發(fā)送方的擁塞窗口+1,即讓擁塞窗口緩慢地增大,按照線性規(guī)律增長;
??7)、當(dāng)出現(xiàn)網(wǎng)絡(luò)擁塞,比如丟包時,將慢開始門限設(shè)為原先的一半,然后將cwnd設(shè)為1,執(zhí)行慢開始算法(較低的起點,指數(shù)級增長);


??上述方法的目的是在擁塞發(fā)生時循序減少主機發(fā)送到網(wǎng)絡(luò)中的分組數(shù),使得發(fā)生擁塞的路由器有足夠的時間把隊列中積壓的分組處理完畢。慢開始和擁塞控制算法常常作為一個整體使用,而快重傳和快恢復(fù)則是為了減少因為擁塞導(dǎo)致的數(shù)據(jù)包丟失帶來的重傳時間,從而避免傳遞無用的數(shù)據(jù)到網(wǎng)絡(luò)??熘貍鞯臋C制是:
??1)、接收方建立這樣的機制,如果一個包丟失,則對后續(xù)的包繼續(xù)發(fā)送針對該包的重傳請求;
??2)、一旦發(fā)送方接收到三個一樣的確認,就知道該包之后出現(xiàn)了錯誤,立刻重傳該包;
??3)、此時發(fā)送方開始執(zhí)行“快恢復(fù)”算法:
??*1、慢開始門限減半;
??*2、cwnd設(shè)為慢開始門限減半后的數(shù)值;
??*3、執(zhí)行擁塞避免算法(高起點,線性增長);


??TCP 滑動窗口協(xié)議,窗口過大或過小有什么影響?
??滑動窗口的大小對網(wǎng)絡(luò)性能有很大的影響。
??如果滑動窗口過小,極端的情況就是停止等待協(xié)議,發(fā)一個報文等一個 ACK,會造成通信效率下降。
??如果滑動窗口過大,網(wǎng)絡(luò)容易擁塞,容易造成接收端的緩存不夠而溢出,容易產(chǎn)生丟包現(xiàn)象,則需要多次發(fā)送重復(fù)的數(shù)據(jù),耗費了網(wǎng)絡(luò)帶寬。??



72、TCP與UDP的對比

??TCP、UDP 都是傳輸層協(xié)議,他們的通信機制與應(yīng)用場景不同。
??TCP(Transmission Control Protocol),又叫傳輸控制協(xié)議,UDP(User Datagram Protocol),又叫用戶數(shù)據(jù)報協(xié)議,它們都是傳輸層的協(xié)議,但兩者的機制不同,它們的區(qū)別如下:

特點 TCP UDP
連接性 面向連接 面向非連接
可靠性 可靠 不可靠
傳輸效率

??TCP的優(yōu)點:可靠,穩(wěn)定。TCP的可靠體現(xiàn)在TCP在傳遞數(shù)據(jù)之前,會有三次握手來建立連接,而且在數(shù)據(jù)傳遞時,有確認、窗口、重傳、擁塞控制機制,在數(shù)據(jù)傳完后,還會斷開連接用來節(jié)約系統(tǒng)資源。TCP的缺點:慢,效率低,占用系統(tǒng)資源高,易被攻擊。TCP在傳遞數(shù)據(jù)之前,要先建連接,這會消耗時間,而且在數(shù)據(jù)傳遞時,確認機制、重傳機制、擁塞控制機制等都會消耗大量的時間,而且要在每臺設(shè)備上維護所有的傳輸連接,事實上,每個連接都會占用系統(tǒng)的CPU、內(nèi)存等硬件資源。而且,因為TCP有確認機制、三次握手機制,這些也導(dǎo)致TCP容易被人利用,實現(xiàn)DOS、DDOS、CC等攻擊。
??UDP的優(yōu)點:快,比TCP稍安全。UDP沒有TCP的握手、確認、窗口、重傳、擁塞控制等機制,UDP是一個無狀態(tài)的傳輸協(xié)議,所以它在傳遞數(shù)據(jù)時非???。沒有TCP的這些機制,UDP較TCP被攻擊者利用的漏洞就要少一些。但UDP也是無法避免攻擊的,比如:UDP Flood攻擊……;UDP的缺點:不可靠,不穩(wěn)定,因為UDP沒有TCP那些可靠的機制,在數(shù)據(jù)傳遞時,如果網(wǎng)絡(luò)質(zhì)量不好,就會很容易丟包。
??基于上面的優(yōu)缺點,那么: 什么時候應(yīng)該使用TCP: 當(dāng)對網(wǎng)絡(luò)通訊質(zhì)量有要求的時候,比如:整個數(shù)據(jù)要準(zhǔn)確無誤的傳遞給對方,這往往用于一些要求可靠的應(yīng)用,比如HTTP、HTTPS、FTP等傳輸文件的協(xié)議,POP、SMTP等郵件傳輸?shù)膮f(xié)議。在日常生活中,常見使用TCP協(xié)議的應(yīng)用如下: 瀏覽器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件傳輸…………;什么時候應(yīng)該使用UDP:當(dāng)對網(wǎng)絡(luò)通訊質(zhì)量要求不高的時候,要求網(wǎng)絡(luò)通訊速度能盡量的快,這時就可以使用UDP。 比如,日常生活中,常見使用UDP協(xié)議的應(yīng)用如下:QQ語音、QQ視頻、TFTP ……。
??TCP與UDP區(qū)別總結(jié):
??1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發(fā)送數(shù)據(jù)之前不需要建立連接;
??2、TCP提供可靠的服務(wù)。也就是說,通過TCP連接傳送的數(shù)據(jù),無差錯,不丟失,不重復(fù),且按序到達;UDP盡最大努力交付,即不保證可靠交付;
??3、TCP面向字節(jié)流,實際上是TCP把數(shù)據(jù)看成一連串無結(jié)構(gòu)的字節(jié)流;UDP是面向報文的,UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會使源主機的發(fā)送速率降低(對實時應(yīng)用很有用,如IP電話,實時視頻會議等);
??4、每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信;
??5、TCP首部開銷20字節(jié);UDP的首部開銷小,只有8個字節(jié);
??6、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道;

72.1、可靠性補充

??在通信的角度來看,可靠即要確保通信雙方的通信信息不會丟失,若丟失了保證能夠?qū)ζ溥M行恢復(fù),并且收到的信息內(nèi)容與原發(fā)送內(nèi)容一樣。
??在 TCP 中,傳輸報文都是通過建立的虛擬連接來進行傳輸,發(fā)送端傳輸?shù)拿恳粋€ TCP報文,都會對其進行編號(編號是由于網(wǎng)絡(luò)傳輸?shù)脑?,發(fā)送的報文可能會亂序到達,因此需要根據(jù)編號對報文進行重排),并且開啟一個計時器;當(dāng)接收端收到報文后,并且通過校驗和對收到的報文數(shù)據(jù)進行校驗,若校驗成功則會返回一個確認報文,告知發(fā)送端我已經(jīng)成功收到該報文了;若發(fā)送端在計時器結(jié)束前仍未收到確認報文,則認為接收端接收失敗,則會重傳該報文;服務(wù)端若收到重復(fù)報文(根據(jù)編號發(fā)現(xiàn)已經(jīng)是收到了),則會將該報文丟棄。
??UDP不需要確保服務(wù)端一定能收到或收到完整的數(shù)據(jù)。它僅僅提供了校驗和機制來保障一個報文是否完整,若校驗失敗,則直接丟棄報文,不做任何處理。
??基于TCP協(xié)議的應(yīng)用層協(xié)議:http、ftp、telnet、smtp;
??基于UDP協(xié)議的應(yīng)用層協(xié)議:dns、rip、tftp;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容