1. 程式人生 > 其它 >計網知識

計網知識

TCP和UDP的區別?

  • TCP是面向連線的,是可靠的傳輸。UDP是不面向連線的,是不可靠的傳輸。
  • TCP是以位元組流傳輸的,UDP是以報文為單位傳輸的。雖然TCP傳輸的資料沒有邊界劃分,但是資料的到達是有序且可靠的。而UDP雖然包與包之間有明確的界限,但是可能會有種種原因導致丟包或者亂序。
  • TCP的首部較長,最小為20位元組,傳輸的時候開銷較大,而UDP是固定首部且只有8個位元組。再加上UDP是不面向連線的,所以UDP會比TCP更快。
  • 所以像實時性比較高的競技遊戲王者榮耀,使用的就是UDP協議,而像是魔獸世界這種MMORPG型別的,使用的是TCP協議(為了確保高延遲狀態下游戲仍然能執行)

可靠:可靠指的是接收方從快取區讀出的資料和傳送方傳送的是完全一致的

為什麼說TCP是面向位元組流的而UDP是面向報文的?

TCP會有一個”快取區“,用來存放等待發送的資料,當TCP決定能傳送的時候就會把快取區中的資料發出,同時TCP還會根據網路擁堵狀況來決定每個報文段的大小,也就是說它會控制本次傳送要從快取區中取走多少資料。而UDP更像是一個傳遞者,它從應用層拿到什麼資料就會發送什麼資料,不進行長度的拆分或者合併(由應用層控制),所以說它是一個包一個包傳送的

粘包問題?

UDP不會有粘包問題,只有使用TCP才會遇到。準確的來說粘包並不是TCP的問題,是程式設計師在接收方解析資料時碰到的難題。

因為TCP決定了每個報文段的大小,也就是說每個報文段裡頭可能含有多個細小的包,或者說一個完整的包再加上下一個包的一部分資訊。無法區分這一串沒有邊界的資料流資訊就是粘包問題。

如何解決粘包問題?

  • 一種方法是固定每個包的長度,這樣子接收方在接受的時候可以定長掃描。缺點也很明顯,如果包的大小參差不齊那麼會很影響效率,優點是很簡單。
  • 另一種辦法是在內容中新增一個定長的頭部標記。接收方在接受資料的時候會先定長的掃描這個標記,然後就能得到一個包的大小是多少。這個包在同一個報文段內結束也好,延伸到下一個報文段也好,接收方都能很好的識別。然後再掃描下一個頭部標記,如此迴圈

TCP的連線管理是怎麼樣的?

  • 連線建立(三次握手)
  • 資料傳送(可靠)
  • 連線釋放(四次揮手)

三次握手是怎樣的?

首先客戶端會給伺服器傳送一條連線請求報文,這條報文段不包含應用層傳下的資料,這是第一次握手。

然後當服務端接受到客戶端的連線請求的時候,會為這個連線分配各種必要的資源,然後回覆一個確認報文,也不包含應用層資料,代表同意此次連線,這是第二次握手。

最後當客戶端接收到服務端發來的確認報文時,自身會為這次連線也分配各種必要的資源,然後再向服務端傳送確認報文,這是確認的確認,這條確認的確認可以攜帶應用層傳下的資料,兩者之間的通訊正式開始,這是第三次握手。

為什麼是三次握手而不是兩次或者四次

由於網路擁塞,連線請求傳送方可能會發送多條連線請求,若只是兩次握手的話無法區分哪些是過期的請求,這樣子會建立起一個”歷史連線“,造成雙方資源的浪費

三次連線就能解決的問題沒有必要使用四次連線

四次揮手是怎樣的?

首先主動斷開連線方會發送一個連線釋放報文(假設是客戶端主動請求關閉),然後客戶端會停止傳送資料,這是第一次揮手。

然後當服務端接收到客戶端的釋放請求後,會回覆一個確認報文,這個時候的連線處於半關閉狀態,此時服務端依然能向客戶端傳送未發完的資料,這是第二次揮手

當服務端的訊息全部發送完成後,會再向客戶端傳送一次連線釋放報文,之後服務端也不再發送資料,這是第三次揮手

最後客戶端接收到服務端這條連線釋放報文後,會迴應一個確認報文。然後進入等待狀態,若這段時間內服務端無再發送報文過來,那麼連線徹底關閉,等待狀態的時間為報文壽命的兩倍。這是第四次揮手

為什麼是四次?

因為當一方主動斷開連線時,另一方可能還會有未完成的資料需要傳送和處理

各端是如何區分不同的報文的?

TCP首部設有6個控制位,用來區分不同的報文,如確認位ACK,同步位SYN,終止位FIN。

為什麼說TCP是可靠的?

  • 重傳機制
  • 流量控制機制
  • 擁塞控制機制

首先TCP能夠做到資料的有序傳輸,而且不丟包。為了保證這兩點就需要重傳機制。首先接收端會根據報文頭部中的序列號來判定資料的接受是否是有序的。同時接收端在接受一個序號正確的資料時,會迴應一個ACK報文,代表在這之前所有的資料都正確接受了,如果發生了丟包,那麼接收端將會發送重複的ACK報文,傳送端會根據超時重傳或者快速重傳機制來重新發送丟失的報文。

流量控制就是傳送方動態調整發送速率使接收方來得及接受,具體實現是傳送方從接受方傳送的ACK確認報文中的RWND視窗欄位來動態調整滑動視窗的大小,以此來達到流量控制

擁塞控制首先會有一個ssthresh門限值,在門限值之前滑動視窗的大小指數增長,達到門限值之後進入擁塞避免階段,視窗加法增長。當遇到擁塞的時候,視窗會立刻置為1,然後將新的門限值設定為遇到擁塞時視窗大小的一半,之後如此反覆

為什麼TCP傳輸的時候需要有滑動視窗

滑動視窗太大或太小會怎麼樣

幀同步與狀態同步

https://zhuanlan.zhihu.com/p/36884005

王者榮耀為什麼要使用幀同步

區別

主要區別就是:

幀同步的戰鬥邏輯是寫在客戶端的,伺服器負責定時轉發玩家的操作,下發到各個客戶端上,然後再在客戶端上進行計算。

狀態同步的戰鬥邏輯是寫在伺服器上的,伺服器根據玩家傳來的各種操作資訊進行計算,然後講計算的結果(玩家的位置,血量等資訊)下方給客戶端,客戶端再做一個數據的體現

遊戲舉例

王者榮耀等MOBA遊戲使用的是幀同步,因為地圖較小,玩家固定(一局只有十個人)

絕地求生,魔獸世界等FPS,MMORPG遊戲使用的是狀態同步,因為地圖較大,玩家多。且MMORPG中玩家上下線更為頻繁,斷線重連實現更為簡單。並且如果這兩種型別的遊戲並不能幀同步實現,因為客戶端無法承載大量玩家的操作計算

適用場景

幀同步適合單局時間短,玩家數量少且固定,而且要求公平的遊戲

狀態同步適合玩家多,對安全性要求高,玩家上下線頻繁的遊戲

其實兩者並不是有你沒我,有我沒你的關係,一個遊戲可能兩種同步方式都有使用到

優缺點

優缺點主要從這幾個點來分析:流量消耗,網路延遲,斷線重連,開發效率,打擊感,安全性,效能,公平

  • 流量消耗:幀同步的遊戲由於只需要傳遞操作序列,所以一局比賽下來流量消耗幾乎是固定的,而狀態同步的遊戲會隨著遊戲體量的增加,複雜度的上升而導致流量消耗加大。網速較慢的玩家或流量有限的玩家玩狀態同步的遊戲會比較吃虧

  • 網路延遲:幀同步的遊戲如果網路較為較差,使用者體驗差。狀態同步使用者體驗則不怎麼明顯

  • 斷線重連:幀同步的遊戲需要從第一幀開始計算,短線重連時間長(遊戲進行的時間越長重連載入的時間越長),而狀態同步只需要拉去當前最新的資訊即可

  • 開發效率:幀同步的開發效率更高,處理完伺服器的下發操作序列後,遊戲開發起來和單機遊戲類似。狀態同步開發難度更高,很多時候需要保證伺服器與客戶端的每一個角色物件的狀態之間保持一致,但事實上你很難做到一致

  • 打擊感:肯能是因為狀態同步每個角色物件的狀態之間很難保持一致,所以無法做到完美的打擊感(又比如射擊遊戲中要產生100個子彈,這又是要想伺服器上傳大量的資訊,增加了消耗,所以FPS遊戲的物理模擬等操作都是在客戶端上進行的);而幀同步客戶端模擬的是玩家操作序列,和單機遊戲一樣,能做出很好的打擊效果

  • 安全性:狀態同步遊戲的安全性高,因為邏輯計算都是在伺服器上執行的,而幀同步的遊戲卻可以通過修改記憶體中的資料來實現作弊。狀態同步的遊戲比如MMORPG,修改數值對遊戲的影響極高,因為遊戲機制是一個“世界”而不是一局一局的比賽;相反,幀同步的遊戲有作弊的玩家也是影響一局比賽,可通過玩家舉報和封禁的方式來治理

  • 效能:幀同步的遊戲需要在客戶端上計算所有玩家的操作,幀同步的遊戲不能裁剪(裁剪掉了它要是再出現在玩家中的視野怎麼辦,重新計算一邊幀操作嗎,這是不合理的),如果同屏有大量玩家的話,邏輯優化的壓力會很大,因為這些實體的操作都需要經過客戶端來計算;而狀態同步可以通過裁剪的方式,只顯示玩家附近的角色,提高效能

  • 幀同步由於是接受伺服器定時下發的操作幀,所以較為公平,網速特別快的玩家不會提前得到操作(即使到了也得等到伺服器的下發頻率到才能轉發);而狀態同步的話,網速快的玩家資料先到達伺服器,伺服器優先處計算後傳送給對應的客戶端,相對來說沒那麼公平(狀態同步是服務端狀態改變就同步,幀同步是定時下發)