前言:記錄了總6w字的面經(jīng)知識點,文章中的知識點若想深入了解,可以點擊鏈接學習。由于文本太多,按類型分開。這一篇是 網(wǎng)絡?常問問題總結(jié),有幫助的可以收藏。
?1. TCP與UDP的區(qū)別
區(qū)別 |
UDP |
TCP |
是否連接 |
不連接 |
面向連接 |
是否可靠 |
不可靠 |
可靠傳輸(傳輸過程中會丟失,但會重發(fā))使用流量控制和擁塞控制 |
連接對象個數(shù) |
支持一對一,一對多,多對一,多對多交互通信。 |
僅支持一對一通信。 |
傳輸方式 |
面向報文 |
面向字節(jié)流 |
數(shù)據(jù)邊界 |
保存數(shù)據(jù)邊界 |
不保存數(shù)據(jù)邊界 |
速度 |
速度快 |
速度慢 |
發(fā)送消耗 |
輕量級(因為 UDP 傳輸?shù)男畔⒅胁怀袚魏伍g接創(chuàng)造連接,保證交貨或秩序的的信息。這也反應在包頭大小。) |
重量級 |
首部開銷 |
首部開銷小,僅8個字節(jié) |
首部開銷大,最小20字節(jié),最大60字節(jié)。 |
有序性 |
不提供有序性的保證 |
TCP 保證了消息的有序性,即使到達客戶端順序不同,TCP 也會排序。 |
應用場景 |
IP電話,視頻會議,直播,以及FPS競技類的使用UDP幀同步。 |
要求可靠傳輸?shù)膽美缥募鬏?,以及MMO類的TCP狀態(tài)同步。 |
2. 幀同步與狀態(tài)同步
2.1 幀同步
????????讓每個客戶端在相同的時刻發(fā)送游戲數(shù)據(jù)到服務端,服務器廣播分發(fā)所有客戶端的數(shù)據(jù),然后客戶端根據(jù)服務端發(fā)來的數(shù)據(jù)做出相應的邏輯處理,保證每個客戶端在同一時刻所有的數(shù)據(jù)都是一致同步的。客戶端做游戲邏輯處理。
核心思想: 相同的輸入+相同的時機=相同的表現(xiàn)
同步的實現(xiàn):
- 同步隨機種子
- 客戶端上傳當前邏輯幀的操作(幀索引+游戲操作)
- 服務器廣播客戶端操作
????????幀同步可以說同步的是操作(輸入)-服務器收到每個客戶端當前的輸入,將數(shù)據(jù)廣播到所有客戶端,客戶端針對其他客戶端的操作,做出邏輯處理,使得所有客戶端在每一時刻的數(shù)據(jù)都是一致的。
優(yōu)點:
- 單次同步數(shù)據(jù)很小,傳輸速率快,因為數(shù)據(jù)的邏輯處理主要是在客戶端,服務器只起到分發(fā)同步的作用。
- 服務端壓力小。
- 更容易實現(xiàn)錄像功能,因為是幀同步,每一個時刻的幀序列都有記錄,可以很好的還原游戲過程。
- 開發(fā)效率高,可以部分當作單機游戲來開發(fā)。
- 游戲精準度更高,能呈現(xiàn)更好的打擊感、音效、特效等反饋、以及動作的反饋、動作的頻率也可以更高。
- 流量消耗小,因為傳輸?shù)臄?shù)據(jù)量更少。大部分邏輯處理都在客戶端處理好了。
缺點:
????????1.反外掛能力弱。因為主要的數(shù)據(jù)處理是在客戶端。
????????2.網(wǎng)絡要求更高,因為是是實時同步,一旦客戶端網(wǎng)絡延遲過高,很容易影響用戶體驗,產(chǎn)生網(wǎng)絡抖動。
????????3.斷線重連難度很大,因為一旦掉線,本地數(shù)據(jù)丟失了,需要從服務器逐幀來讀取游戲進度,直到與當前游戲進度一直。如果直接從當前游戲進度開始進行同步,是很容易出現(xiàn)數(shù)據(jù)錯誤的。
2.2 狀態(tài)同步
????????客戶端將數(shù)據(jù)發(fā)送到服務端,服務端根據(jù)每個客戶端發(fā)來的數(shù)據(jù)做出處理,再將處理完的數(shù)據(jù)廣播發(fā)送到所有客戶端,客戶端根據(jù)數(shù)據(jù)進行數(shù)據(jù)表現(xiàn)。服務端做游戲邏輯處理。
優(yōu)點:
- 反外掛能力強,因為大部分數(shù)據(jù)處理都是在服務端。
- 網(wǎng)絡要求不高。
- 玩家可以隨時加入到一個開始的戰(zhàn)局,只需要同步當前戰(zhàn)局內(nèi)的所有玩家當前的狀態(tài)即可。
缺點:
- 傳輸數(shù)據(jù)大,傳輸速度慢。因為客戶端會將大量數(shù)據(jù)傳輸給服務端,再由服務端進行邏輯處理,再分發(fā)給所有客戶端。
- 服務端壓力大
- 回放較難還原
2.3 區(qū)別
????????狀態(tài)同步:比較多的MMO
????????幀同步:Dota,紅警 ?RTS(戰(zhàn)略)類游戲,Moba類。
3. OSI七層模型有哪些,每一層的作用
????????應用層:為應用程序提供服務
????????表示層:數(shù)據(jù)格式轉(zhuǎn)化,兼容并且適合傳輸?shù)母袷剑ㄆ鸬椒g的作用)、 ?數(shù)據(jù)加密。
????????會話層:建立、管理和維護會話,它主要負責數(shù)據(jù)傳輸中設置和維護 ??網(wǎng)絡中兩臺設備之間的通信連接。
????????傳輸層:建立、管理和維護端到端的連接,
????????網(wǎng)絡層:IP選址和路由選擇
????????數(shù)據(jù)鏈路層:分幀,確定mac地址
????????物理層:真正的物理設備傳輸數(shù)據(jù),物理層將2進制數(shù)據(jù)利用電脈沖 ??在物理媒介上實現(xiàn)比特流的傳輸。
4. TCP/IP協(xié)議棧各個層次及分別的功能
????????應用層: 用來處理特定的應用,針對不同的應用提供了不同的協(xié)議, 例如進行文件傳輸時用到的FTP協(xié)議,發(fā)送email用到的 SMTP等。對應協(xié)議:FTP、HTTP、SMTP、DNS等。
????????傳輸層: ?主要功能是提供應用程序之間的通信,這一層主要是 ??TCP/UDP協(xié)議。
????????網(wǎng)絡層: ?處理分組在網(wǎng)絡中的活動,例如路由選擇和轉(zhuǎn)發(fā)等,這一 ?層主要包括IP協(xié)議、ARP、ICMP協(xié)議等。
????????網(wǎng)絡接口層:這是協(xié)議棧的最低層,對應OSI的物理層和數(shù)據(jù)鏈路層, ?主要完成數(shù)據(jù)幀的實際發(fā)送和接收。
5. TCP的三握四揮
5.1 三次握手
5.1.1 概念
- 首先 Client 端發(fā)送連接請求報文。
- Server 段接收鏈接后回復ACK 報文,并為這次連接分配資源。
- Client 端接收到 ACK 報文后也向 Server 段發(fā)生 ACK 報文,并分配資源,這樣 TCP 連接就建立了。
小結(jié):
????????三次握手的關鍵是要確認對方收到了自己的數(shù)據(jù)包,這個目標就是通過 “確認號(Ack)”字段實現(xiàn)的。計算機會記錄下自己發(fā)送的數(shù)據(jù)包序號 Seq,待收到對方的數(shù)據(jù)包后,檢測 “確認號(Ack)字段”,看 Ack = Seq + 1 是否成立,如果成立說明對方?正確收到了自己的數(shù)據(jù)包。
5.1.2 為什么要三次握手(常問)
? ? ? ? 1. 如果只有一次握手,Client不能確定與Server的單向連接,更加不能確定Server與Client單向連接;
? ? ? ? 2. 如果只有兩次握手,Client確定與Server的單向連接,但是Sevrer不能確定與Client的單向連接;
? ? ? ? 3. 只有三次握手,Client與Server才能相互確認雙向連接,實現(xiàn)雙方的數(shù)據(jù)傳輸。
5.2 四次揮手
5.2.1 概念
- Client 發(fā)送一個 FIN,用來關閉 Client 到 Server 的數(shù)據(jù)傳送, Client 進行 FIN_WAIT_1 狀態(tài)。
- Server 收到FIN 后,發(fā)送一個 ACK 到 Client,Server 進入CLOSE_WAIT 狀態(tài),Client收到ACK,進入FIN_WAIT_2 狀態(tài)。
- Server 發(fā)送一個 FIN,用來關閉 Server 到Client 的數(shù)據(jù)傳送,Server 進入 LAST_ACK 狀態(tài)。
- Client 收到 FIN 后,Client 進入 TIM_WAIT 狀態(tài),發(fā)送 ACK 給Server,Server 進入 CLOSED 狀態(tài),TIME-WAIT一般為2個MSL(報文最長壽命),如果在這個時間段內(nèi)沒有收到服務端的超時重發(fā),說明客戶端發(fā)過去的ACK服務端收到了并且已經(jīng)關閉連接,客戶端才進入CLOSED狀態(tài)。完成四次握手。
5.2.2 為什么要四次揮手(常問)
????????服務端在收到客戶端的釋放報文時,可能自己的數(shù)據(jù)報還沒有發(fā)完,所以不會直接返回FIN+ACK,而只先返回一個ACK,表示自己收到了客戶端的釋放請求(第二次揮手)。等到服務端報文發(fā)完以后,在返回FIN(第三次揮手)。
那么,我們是否可以在服務器端數(shù)據(jù)傳送完成后,再返回FIN+ACK呢?中間就可以省略一次ACK了?(省略第二次揮手)
????????試想一下,如果服務端還有很多數(shù)據(jù)需要傳送,耗時長,客戶端在發(fā)送釋放報文后,一直沒有收到反饋,那么他會認為服務端沒有收到我的FIN,因此就會不停的重發(fā)FIN。(第一次揮手)
????????所以最好的辦法就是,客戶端發(fā)送FIN,服務端回復ACK,表示我已經(jīng)收到了,但是我在忙,你等等,我處理完成后聯(lián)系你。服務端數(shù)據(jù)傳送完成后,發(fā)送FIN給客戶端,客戶端再回復ACK。
????詳細請看:
為什么TCP需要三次握手,四次揮手?_小菜雞的日常問題的博客-CSDN博客_為什么要四次揮手文章目錄為什么需要三次握手?三次握手為什么不是兩次或者四五六次握手呢?為什么需要四次揮手四次揮手那為什么是兩個MSL呢:為什么不是三次揮手呢?什么是SYN Flood(洪水) 攻擊半連接隊列和全連接隊列、SYN TimeoutSYN Flood攻擊防御SYN Flood攻擊TCP是一個面向連接的,可靠的,字節(jié)流的,傳輸層的協(xié)議,在數(shù)據(jù)發(fā)送前,通信雙方需要建立‘連接’,來保存一份關于對方的信息。它...https://blog.csdn.net/qq_33426324/article/details/105344168
5.2.3 為什么不能直接CLOSE狀態(tài),必須要先設置TIME_WAIT(2個MSL)狀態(tài)
????????理論上,四個報文都發(fā)送完畢,就可以直接進入CLOSE狀態(tài)了,但是可能網(wǎng)絡是不可靠的,有可能客戶端發(fā)送給服務的的最后一個ACK丟失。一段時間后,服務端收不到最后的ACK,認為客戶端沒有收到FIN請求(第三次揮手),進行超時重發(fā),但是客戶端已經(jīng)關閉了,不會給響應。(理論上來說 服務器超時重發(fā)5次后,就會主動斷開連接,這樣數(shù)據(jù)既不會丟失也不會錯亂,是可以的,但是這樣不符合可靠連接。)
????????此時若舊的客戶端直接CLOSE沒有TIME_WAIT狀態(tài),新的客戶端建立與服務端之間的連接,如果新連接和老連接的端口是一樣的。假設老連接還有一些數(shù)據(jù),因為網(wǎng)絡或者其他原因,一直滯留沒有發(fā)送成功,新連接建立后,就直接發(fā)送到新連接里面去了,造成數(shù)據(jù)的紊亂,因此,我們需要2*MSL的TIMEWAIT狀態(tài),讓滯留在網(wǎng)絡中的報文失效,再去建立新的連接。
????????所以簡單來說TIME_WAIT狀態(tài)中的2個MSL(TIME_WAIT狀態(tài)作用)
- 用來重發(fā)可能丟失(第四次揮手)的ACK報文
- 避免服務器有了新的數(shù)據(jù)需要發(fā)送給客戶端。
6. TCP為什么穩(wěn)定
????????與 亂序重排、應答確認、報文重傳 和 流量控制 四種機制有關。
6.1 亂序重排
????????由于網(wǎng)絡或“多線程”等因素,接收方收到的數(shù)據(jù)段很可能是亂序的,不過因為每個 TCP 封裝都有序號,接收方重組起來非常容易。
6.2 應答確認
????????計算機會記錄下自己發(fā)送的數(shù)據(jù)包序號 Seq,待收到對方的數(shù)據(jù)包后,檢測 “確認號(Ack)字段”,看 Ack = Seq + 1 是否成立,如果成立說明對方正確收到了自己的數(shù)據(jù)包。
????????不過為了提高效率,客戶端一次有可能發(fā)送上千條數(shù)據(jù),根據(jù)服務端返回客戶端的確認號,判斷是否為這上千條中最后一條的序列號+1,即發(fā)送5000條數(shù)據(jù)包,判斷服務器發(fā)送給客戶端的Ack是否為5001,等式成立即為接受完整。
6.3 報文重傳
????????TCP 的報文重傳有兩種獨立的辦法。一種是超時重傳,一種是快速重傳。
6.3.1 超時重傳
????????因為網(wǎng)速 并不是穩(wěn)定的,傳輸時的每個報文的延時也不一樣。TCP 會根據(jù)報文的往返時間(RTT)自動調(diào)整超時重傳時間(RTO)。發(fā)送方每發(fā)一個報文段都會開始計時,如果時間超過 RTO 還沒收到這個報文段的確認,就重傳該報文段。
6.3.2 快速重傳
????????接收方收到序號X 后,回復X+1的確認號,希望收到X+1序號報文,但沒有收到,卻收到了比X+1還要大的報文,就連續(xù)發(fā)出確認號X+1的報文,如果發(fā)送方連續(xù)三次收到重復的確認號,立即重發(fā)該報文段,而不管是否超時。
6.4 流量控制
????????首先要明白一點,應用程序不論發(fā)送還是接收數(shù)據(jù),都會先把數(shù) 據(jù)放入緩沖區(qū),再從緩沖區(qū)中發(fā)出或讀取數(shù)據(jù)。這個緩沖區(qū)大小,反映了應用程序一次能處理數(shù)據(jù)的能力。如果接收方應用程序處理速度比發(fā)送方的發(fā)送速度慢,就會造成接 收方緩沖區(qū)“溢出”。實際上,發(fā)送方發(fā)送速度和接收方處理速度很難一致。 這就需要 window 來調(diào)整了。 TCP 在三次握手建立連接時,會協(xié)商雙方緩沖區(qū) window 大小。如果因為接收方處理速度較慢,接收方會通過 window 告知發(fā)送方,實現(xiàn)動態(tài)調(diào)整,避免“溢出”。
????????所謂流量控制就是讓發(fā)送發(fā)送速率不要過快,讓接收方來得及接 收。利用滑動窗口機制就可以實施流量控制。原理這就是運用 TCP 報文段中的窗口大小字段來控制,發(fā)送方的發(fā)送窗口不可以大于接收方發(fā)回的窗口大小。
????????考慮一種特殊的情況,就是接收方若沒有緩存足夠使用,就會發(fā)送零窗口大小的報文,此時發(fā)送放將發(fā)送窗口設置為0,停止發(fā)送數(shù)據(jù)。之后接收方有足夠的緩存,發(fā)送了非零窗口大小的報文,但是這個報文在中途丟失的,那么發(fā)送方的發(fā)送窗口就一直為零導致死鎖。解決這個問題,TCP 為每一個連接設置一個持續(xù)計時(persistence timer)。只要 TCP 的一方收到對方的零窗口通知,就啟動該計時器,周期性的發(fā)送一個零窗口探測報文段。對方就在確認這個報文的時候給出現(xiàn)在的窗口大小。
7. TCP 擁塞控制
????????擁塞的發(fā)生是因為路由器緩存溢出,擁塞會導致丟包,但丟包不一定觸發(fā)擁塞。擁塞控制是快速傳輸?shù)幕A。一個擁塞控制算法一般包括慢啟動算法、擁塞避免算法、快速重傳算法、快速恢復算法四部分。
8. 斷線重連
????????當檢測到客戶端斷線時,斷開當前客戶端 Socket;重新根據(jù)IP和 端口號重建新的 Socket。當連接上服務器網(wǎng)關后,攜帶 token,向服務器發(fā)送斷線重連協(xié)議。
9. 進程和線程
????????進程:一個應用程序相當于一個進程,是操作系統(tǒng)資源分配的基本單位。 一個進程擁有多個線程。更安全。
????????線程:是程序的實際執(zhí)行者。線程是操作系統(tǒng)能夠進行運算調(diào)度的最小單位。它被包含在進程之中,一個線程只有一個進程。效率高。
????????線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.?
9.1 什么是線程爭用
????因為進程中可存在多個線程,線程間均可訪問主線程資源。所以若線程間爭搶資源,可能導致數(shù)據(jù)混亂。???
9.2 如何解決線程爭用
????只要避免同一時間只有一個線程來訪問共享數(shù)據(jù)就OK了。
????????1.Monitor(監(jiān)控器)
????????2.Lock,是對Monitor的封裝,簡單易用。
9.3?線程和協(xié)程的區(qū)別是什么
9.4?前臺線程 和 后臺線程
一:線程有兩種:前臺線程和后臺線程。
? ? ? ?區(qū)別是:應用程序必須運行完所有的前臺線程才可以退出;?
? ? ? ? ? ? ? ? ? ? ?而對于后臺線程,應用程序則可以不考慮其是否已經(jīng)運行完畢而直接退出,所有的后臺線程在應用程序退出時都會自動結(jié)束。
二:.net環(huán)境使用Thread建立的線程默認情況下是前臺線程,即線程屬性IsBackground=false
????????在進程中,只要有一個前臺線程未退出,進程就不會終止。主線程就是一個前臺線程。
????????而后臺線程不管線程是否結(jié)束,只要所有的前臺線程都退出(包括正常退出和異常退出)后,進程就會自動終止。
三:使用方法
? ? ? ?一般后臺線程用于處理時間較短的任務,如在一個Web服務器中可以利用后臺線程來處理客戶端發(fā)過來的請求信息。
? ? ? ?而前臺線程一般用于處理需要長時間等待的任務,如在Web服務器中的監(jiān)聽客戶端請求的程序,或是定時對某些系統(tǒng)資源進行掃描的程序。
四:注意
????????在調(diào)用Start方法之前設置線程的類型,否則一但線程運行,將無法改變其類型。
9.5 針對于效率與安全方面,兩者區(qū)別
????????線程執(zhí)行開銷小,但是不利于資源的管理和保護。線程適合在SMP機器(雙CPU系統(tǒng))上運行。
????????進程執(zhí)行開銷大,但是能夠很好的進行資源管理和保護。進程 可以跨機器前移。
使用場景:
- 對資源的管理和保護要求高,不限制開銷和效率時,使用多進程。對算力要求高的使用多進程,因為 大量計算用進程,因為操作系統(tǒng)分配的算力是按進程分配的,一個進程的內(nèi)即使有再多的線程,也只能得到一個CPU核心的算力
- 要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多線程。
10. 序列化與反序列化(xml、json、protobuf)
????????序列化 :將對象狀態(tài)轉(zhuǎn)化為可保持或者可傳輸?shù)母袷降倪^程。
????????反序列化 :將已經(jīng)序列化過后的數(shù)據(jù)恢復成原先對象的過程。
擴展:序列化的多種方案
XML
????????指可擴展標記語言(eXtensible Markup Language)。是一種通用和重量級的數(shù)據(jù)交換格式。以文本結(jié)構(gòu)存儲。
優(yōu)點:
- 格式更為標準和統(tǒng)一
- 更容易和其它系統(tǒng)進行遠程交互
- 數(shù)據(jù)共享比較方便
缺點:
????????相比于JSON,由于需要成對的數(shù)據(jù)標簽,數(shù)據(jù)更加的冗余。 而JSON使用鍵值對,壓縮了數(shù)據(jù)空間并且更加可讀。
JSON
????????是一種通用和輕量級的數(shù)據(jù)交換格式。以文本結(jié)構(gòu)存儲。
優(yōu)點:?
????????1 簡單易用開發(fā)成本低
????????2 跨語言
????????3 輕量級數(shù)據(jù)交換
????????4 非冗長性(對比xml標簽簡單括號閉環(huán))
缺點:?
????????1 體積大,影響高并發(fā)
????????2 無版本檢查,自己做兼容
????????3 片段的創(chuàng)建和驗證過程比一般的XML復雜
????????4 缺乏命名空間導致信息混合
????????5 沒有XML格式這么推廣的深入人心和使用廣泛,沒有XML那么通用性
總結(jié):最簡單最通用的應用協(xié)議,使用廣泛,開發(fā)效率高,性能相對較低,維護成本較高。
Protobuf
????????protocol buffer是Google的一種獨立和輕量級的數(shù)據(jù)交換格式。以二進制結(jié)構(gòu)進行存儲。
????????Protobuf是一種以有效并可擴展的格式編碼結(jié)構(gòu)化數(shù)據(jù)的方式。
優(yōu)點
????????1 跨平臺多語言,可自定義數(shù)據(jù)結(jié)構(gòu)。
????????2 字段被編號,新添加的字段不影響老結(jié)構(gòu)。解決了向后兼容問題。
????????3 序列化后體積相比json和xml很小,適合網(wǎng)絡傳輸。
????????4 序列化反序列化速度很快,快于Json的處理速度。
? ? ? ? 5 自動化生成代碼,簡單易用。
????????6 二進制消息,效率高,性能高。
????????7 Netty等框架集成了該協(xié)議,提供了編×××提高開發(fā)效率。
缺點
????????1 二進制格式,可讀性差(抓包dump后的數(shù)據(jù)很難看懂)
????????2 對象冗余,字段很多,生成的類較大,占用空間。
????????3 默認不具備動態(tài)特性(可以通過動態(tài)定義生成消息類型或者動態(tài)編譯支持)
總結(jié):簡單快速上手,高效兼容性強,維護成本較高。
三者比較:
????????1、json:一般的web項目中,最流行的主要還是json。因為瀏覽器對于json數(shù)據(jù)支持非常好,有很多內(nèi)建的函數(shù)支持。
????????2、xml:在webservice中應用最為廣泛,但是相比于json,它的數(shù)據(jù)更加冗余,因為需要成對的閉合標簽。json使用了鍵值對的方式,不僅壓縮了一定的數(shù)據(jù)空間,同時也具有可讀性。
????????3、protobuf:是后起之秀,是谷歌開源的一種數(shù)據(jù)格式,適合高性能,對響應速度有要求的數(shù)據(jù)傳輸場景。因為profobuf是二進制數(shù)據(jù)格式,需要編碼和解碼。數(shù)據(jù)本身不具有可讀性。因此只能反序列化之后得到真正可讀的數(shù)據(jù)。
11. 黏包
11.1 概念
????????多個獨立的包黏在一塊
11.2 考慮時機
????????Tcp連續(xù)發(fā)送消息的時候,會出現(xiàn)消息一起發(fā)送過來的問題。
11.3 產(chǎn)生原因
????????1.發(fā)送端需要等緩沖區(qū)滿才發(fā)送出去,造成粘包(發(fā)送端出現(xiàn)粘包)
????????2.接收端沒有及時接收緩沖區(qū)包數(shù)據(jù),造成一次性接收多個包,出現(xiàn)粘包(接收端出現(xiàn)粘包)
11.4 如何解決
????????1.緩沖區(qū)過大造成了粘包,所以在發(fā)送/接收消息時先將消息的長度作為消息的一部分發(fā)出去,這樣接收方就可以根據(jù)接收到的消息長度來動態(tài)定義緩沖區(qū)的大小。(這種方法就是所謂的自定義協(xié)議,這種方法是最常用的)
????????2.對發(fā)送的數(shù)據(jù)進行處理,每條消息的首尾加上特殊字符,然后再把要發(fā)送的所有消息放入一個字符串中,最后將這個字符串發(fā)送出去,接收方接收到這個字符串之后,再通過特殊標記操作字符串,把每條消息截出來。(這種方法只適合數(shù)據(jù)量較小的情況)
12.? Socket的封包、拆包
12.1 基于TCP的通信程序需要封包、拆包的原因
????????TCP是流協(xié)議,所謂流,就是沒有界限的一串數(shù)據(jù)。但是程序中卻有多種不同的數(shù)據(jù)包,那就很可能會出現(xiàn)如上所說的粘包問題,所以就需要在發(fā)送端封包,在接收端拆包。
12.2 那么如何封包、拆包
????????答:封包就是給一段數(shù)據(jù)加上包頭或者包尾。比如說我們上面為解決粘包所使用的兩種方法,其實就是封包與拆包的具體實現(xiàn)。
13. 并發(fā)/并行/異步/同步
13.1 并發(fā)
????????一個處理器“同時”處理多個任務,CPU通過時間片切換輪流執(zhí)行不同的任務。
????????進程的調(diào)度實際上就是實現(xiàn)了并發(fā),相當于吃飯吃一半,停下來去接電話,接完再吃飯,只是過程很快,做到了像同時運行。
13.2 并行
????????“多個”處理器或者多核處理器同時處理多個任務,兩個線程互不搶占CPU資源,可以同時執(zhí)行任務。
13.3 異步
????????比如我上手機店買手機,服務員去倉庫拿手機,要花一分鐘,我趁這一分鐘才去買水喝,然后回來剛好拿到手機。
????????這個過程就是當程序遇到阻塞,需要等待的時候,程序會先執(zhí)行其他任務,完成任務后回來,剛好上個任務也已經(jīng)完成,可以提高效率。
13.4 同步
????????比如我上手機店買手機,服務員去倉庫拿手機,要花一分鐘,我等了一分鐘后拿到手機才去買水喝。這個過程就是當程序遇到阻塞,需要等待的時候,程序會一直等待阻塞解除或者運行完后才進行下一步執(zhí)行。
14. 找到unity中卡頓的點
????????用unity中的unity profiler 去定位,開啟deep操作,開啟后非常消耗性能,可以找到一個大致的范圍,然后關閉deep,自己編寫一個costume profiler 去縮小范圍。
15. Protobuf
????????protobuf是一種可序列化的數(shù)據(jù)交換格式。于此相同的還有json,xml。
用途:
????????用于通訊協(xié)議、存儲數(shù)據(jù)。網(wǎng)絡信息的傳輸,游戲數(shù)據(jù)的存儲。
優(yōu)點:
- 傳輸數(shù)據(jù)量小,擴展性很好
- 解包封包更小。序列化后的大小是json的1/10是xml1/20;
- 不限制─種語言或一個平臺,高效;因為protobuf數(shù)據(jù)交換格式的代碼是開源的
- 且傳輸數(shù)據(jù)可空(如果一個字段沒有傳值,會自動跳過該字段)。
- 性能好,效率高-存儲消耗小,轉(zhuǎn)化效率高。
- 預生產(chǎn)代碼,無需編寫解析代碼。同行json/xml,在一個平臺使用時,需要使用解析包,解析完后還需要通過反射實例化出對應的類,消耗特別大;而protobuf,如果項目使用c#進行編碼,則會生成對應的c#代碼,其轉(zhuǎn)化生成都是protobuf自己去完成,不需要專門的去編寫。
- 兼容性很好。如果生產(chǎn)的協(xié)議文件已經(jīng)更新了,而本地的文件沒有更新,依舊不影響使用,只不過碰到新的字段會自動跳過。
缺點:
- 相對于json數(shù)據(jù)交換格式,protobuf沒有json更容易讀和調(diào)試。
- 對象冗余,字段多,生成類較大,占用空間,且維護成本高。
性能解析:
????????JSON數(shù)據(jù)傳輸?shù)臄?shù)據(jù)格式:{"id":1," name":"liu ", "age":18, "level":9}有很多冗余數(shù)據(jù):如{} id一樣的字段名符等,而真正需要傳輸?shù)臄?shù)據(jù)其實就是1,liu,18,9;如果進行優(yōu)化,不傳字段名,則需要用分隔符將每個字段分割開進行傳輸,但是一旦兩個字段名的數(shù)據(jù)數(shù)據(jù)格式一樣,一旦一個字段沒有傳值就會出問題。而本來不用傳值的字段這個時候也需要傳入null或者0來避免問題的出現(xiàn)而導致資源的浪費。
protobuf的獨特之舉:
- tag技術
????????將編號左移3位|(或運算)數(shù)據(jù)類型編碼(int32-0 double-1 string/byte/repeated-2)。
????????(編號右邊)
????????如果用一個字節(jié)來存儲字段-則最大編碼只能到15:00001111>>3:01111000(第一位一般不占值),大于15了就需要兩個宇節(jié)來存儲字段了。
????????2. Varint編碼:
????????普通整型4字節(jié):00000000 00000000 00000000 00000000
????????如果發(fā)現(xiàn)其中一個字節(jié)沒有占用,則會自動省略,最少使用一個字節(jié)表示。127是一個字節(jié)表示的最大整型數(shù)值。
protobuf的底層原理:
- protobuf傳輸數(shù)據(jù)的格式是tag以及對應tag的value值,而且數(shù)據(jù)value是可空的;對于value數(shù)據(jù)tag的生成:在定義協(xié)議字段時,需要明確字段的變量類型,以及編號,而tag的值就是編號左移3位|(或)數(shù)據(jù)類型編碼。
- Varint編碼:當傳輸?shù)臄?shù)據(jù)為int型時,會從最高位去檢查當前字節(jié)的各個位是否被占用,如果沒有被占用則省略,最多可以將4字節(jié)的int型用1字節(jié)去表示。
????????詳細請看:
為什么protobuf這么快_May Hacker的博客-CSDN博客_protobuf為什么快文章目錄一、前言二、protobuf優(yōu)點壓縮率高解析快總結(jié)一、前言protobuf全稱protocol buffers,是一種語言無關、平臺無關、可擴展的序列化結(jié)構(gòu)數(shù)據(jù)方法。在用途上,與JSON/XML類似。二、protobuf優(yōu)點壓縮率高解析快多語言支持壓縮率高protobuf基于接口描述語言IDL(Interface Description Language)實現(xiàn)消息結(jié)構(gòu)的定義,傳輸數(shù)據(jù)的兩端都需要定義該消息結(jié)構(gòu),并保存在.proto文件中,這樣就不需要在消息數(shù)據(jù)中定義結(jié)構(gòu)信息,自https://blog.csdn.net/weixin_43889841/article/details/121269448
16. 網(wǎng)絡抖動
什么是網(wǎng)絡抖動
????????如果網(wǎng)絡發(fā)生擁塞,排隊延遲將影響端到端的延遲,并導致通過同一連接傳輸?shù)姆纸M延遲各不相同,而抖動,就是用來描述這樣一延遲變化的程度。
????????他是網(wǎng)絡延時變化,最大延遲與最小延遲的時間差;
????????如最大延遲是20毫秒,最小延遲為5毫秒,那么網(wǎng)絡抖動就是15毫秒,它主要標識一個網(wǎng)絡的穩(wěn)定性。
抖動造成原因
????????如果網(wǎng)絡發(fā)生擁塞,排隊延遲將影響端到端的延遲,并導致通過同一連接傳輸?shù)姆纸M延遲各不相同;
????????當網(wǎng)絡設備無法發(fā)送相同數(shù)據(jù)的流量,因此他們的數(shù)據(jù)包緩沖區(qū)已滿并開始丟棄數(shù)據(jù)包。如果端點上的網(wǎng)絡沒有干擾,則每個數(shù)據(jù)包都會到達。
????????但是,如果端點緩沖區(qū)滿了,會使數(shù)據(jù)包到達的越來越晚,導致抖動。
????????而抖動,就是用來描述這樣一延遲變化的程度。因此,抖動對于實時性的傳輸將會是一個重要參數(shù),比如:VOIP,視頻等。
解決方法
????????數(shù)據(jù)包接收端的抖動緩存;緩存指針隊列對接收到的數(shù)據(jù)包進行排序后,將接收到的數(shù)據(jù)包插入抖動緩存指針隊列的相應位置;
????????抖動緩存指針隊列的出隊線程定時器,以一定時間間隔觸發(fā)出隊線程,出隊線程判斷抖動緩存指針隊列隊頭的數(shù)據(jù)包,是否應該在當前觸發(fā)時刻出隊,如果是,則將該數(shù)據(jù)包出隊。
17. http與https的區(qū)別
????????HTTP協(xié)議以明文方式發(fā)送內(nèi)容,不提供任何方式的數(shù)據(jù)加密。HTTP協(xié)議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。
????????https則是具有安全性的ssl加密傳輸協(xié)議。
????????http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。并且https協(xié)議需要到ca申請證書。HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡協(xié)議,要比http協(xié)議安全。
????????HTTPS協(xié)議的主要作用可以分為兩種:一種是建立一個信息安全通道,來保證數(shù)據(jù)傳輸?shù)陌踩?另一種就是確認網(wǎng)站的真實性。HTTPS在HTTP的基礎上加入了SSL協(xié)議,SSL依靠證書來驗證服務器的身份,并為瀏覽器和服務器之間的通信加密。
????????希望此篇文章可以幫助到更多的同學,此外對現(xiàn)在面臨校招的大三大四的同學,以及熱愛游戲或者即將面臨找工作的朋友,可以點擊下方鏈接,來解決游戲職業(yè)道路的種種困惑,并且還可以學習理論知識的同時,拓寬游戲制作的實踐技能~文章來源:http://www.zghlxwxcb.cn/news/detail-428412.html
游戲行業(yè)大揭秘https://scrm.vipskill.com/CMS/prod/5726/54/home.html?mantisSiteId=175&track_id=__TRACKID__文章來源地址http://www.zghlxwxcb.cn/news/detail-428412.html
到了這里,關于Unity游戲開發(fā)客戶端面經(jīng)——網(wǎng)絡(初級)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!