最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity框架設(shè)計(jì)系列專題:如何設(shè)計(jì)網(wǎng)絡(luò)框架

2022-09-09 15:30 作者:博毅創(chuàng)為  | 我要投稿

在Unity框架設(shè)計(jì)中與游戲服務(wù)器對(duì)接的網(wǎng)絡(luò)框架也是非常重要的一個(gè)模塊,本文給大家分享如何來(lái)基于Unity來(lái)設(shè)計(jì)一個(gè)網(wǎng)絡(luò)框架, 主要的講解以下幾個(gè)點(diǎn):

(1) TCP半包粘包, 長(zhǎng)連接與短連接, IO阻塞;

(2) Tcp Socket與UDP Socket 的技術(shù)方案;

(3) Unity的序列化與反序列化技術(shù)方案;

(4) TCP的封包與拆包;

(5) 基于http的短連接技術(shù)方案;

(6) Unity 網(wǎng)絡(luò)框架設(shè)計(jì)與實(shí)現(xiàn)原理;

?

TCP半包粘包, 長(zhǎng)連接與短連接, IO阻塞

?

TCP 是可靠的網(wǎng)絡(luò)傳送協(xié)議,網(wǎng)絡(luò)傳輸?shù)讓用堪l(fā)送一個(gè)TCP數(shù)據(jù)包,就要等對(duì)方確認(rèn),收到確認(rèn)消息以后才能發(fā)下一個(gè)TCP數(shù)據(jù)包。當(dāng)我們?cè)趹?yīng)用層發(fā)送一個(gè)應(yīng)用層的數(shù)據(jù)包的時(shí)候,TCP網(wǎng)絡(luò)底層可能會(huì)把這個(gè)應(yīng)用層的數(shù)據(jù)包分成若干”TCP數(shù)據(jù)包”,通過(guò)網(wǎng)絡(luò)底層發(fā)出去。那么這里就會(huì)有一個(gè)問(wèn)題,應(yīng)用層發(fā)的數(shù)據(jù)包有可能被拆散成幾個(gè)”TCP數(shù)據(jù)包”發(fā)出去,我們?cè)诹硗庖欢私邮盏臅r(shí)候,可能要把這些拆散的包組合起來(lái)。這個(gè)就是”半包”。底層有可能把兩個(gè)應(yīng)用層的數(shù)據(jù)包分到一個(gè)”TCP數(shù)據(jù)包”發(fā)過(guò)去,接收到后,一部分是屬于上一個(gè)應(yīng)用層的數(shù)據(jù)包,一部分屬于下一個(gè)應(yīng)用層的數(shù)據(jù)包,這個(gè)叫做”粘包”。

TCP 是面向連接的,服務(wù)端與客戶端通過(guò)TCP 連接來(lái)傳送數(shù)據(jù),如果連接一直在,發(fā)送完數(shù)據(jù)后,不關(guān)閉連接,下一次發(fā)數(shù)據(jù)可以直接發(fā)送,我們叫做長(zhǎng)連接。如果發(fā)送數(shù)據(jù)先建立連接,數(shù)據(jù)發(fā)送完畢后,馬上關(guān)閉連接,下次要發(fā)送數(shù)據(jù)重新建立連接,這種叫做”短連接”。長(zhǎng)連接一直存在,優(yōu)點(diǎn)就是客戶端與服務(wù)端隨時(shí)可以相互通訊,但是一直占用連接資源。短連接是不占用連接資源,但是只有客戶端能像服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端在斷開(kāi)連接后無(wú)法主動(dòng)通知客戶端。

IO阻塞指的是我們的CPU處理數(shù)據(jù)的速度,遠(yuǎn)遠(yuǎn)大于網(wǎng)絡(luò)的傳送速度。當(dāng)我們要發(fā)送數(shù)據(jù)的時(shí)候,CPU調(diào)用IO的接口,把數(shù)據(jù)從內(nèi)存拷貝到網(wǎng)絡(luò)底層,等待底層把數(shù)據(jù)傳送過(guò)去后,CPU調(diào)用的IO函數(shù)返回,而這個(gè)過(guò)程,CPU在等待網(wǎng)絡(luò)把數(shù)據(jù)發(fā)出去,線程掛起了,這個(gè)我們叫做IO阻塞。

?

Tcp Socket與UDP Socket 的技術(shù)方案

?

了解完網(wǎng)絡(luò)的一些基本概念以后,接下來(lái)看下使用TCP/UDP Socket用哪些技術(shù)方案。Unity其實(shí)是作為網(wǎng)絡(luò)的客戶端,而客戶端只要去連接服務(wù)端與服務(wù)器通訊就可以了,不用像服戶端同時(shí)處理N個(gè)客戶端的數(shù)據(jù)傳送。所以客戶端Socket非常的簡(jiǎn)單。Unity客戶端的Socket我們用哪個(gè)插件呢?其實(shí)這種完全不需要用什么插件,直接使用OS為我們提供的Socket的相關(guān)API就可以了。

TCP Socket 面向連接的,使用流程如下:

1: 客戶端Connect服務(wù)端,建立Socket連接;

2: 調(diào)用Socket的Send函數(shù)發(fā)送數(shù)據(jù);

3: 調(diào)用Sokcet Recv函數(shù)從Socket上讀取數(shù)據(jù);

4: 關(guān)閉Socket 的連接;

UDP Socket的使用, UDP Socket不是面向連接的,只是調(diào)用底層的網(wǎng)絡(luò)協(xié)議,直接把數(shù)據(jù)包發(fā)往特定地址+端口。所以直接是SendTo(網(wǎng)絡(luò)地址+端口), RecvFrom(網(wǎng)絡(luò)地址+端口)

TCP/UDP Socket已經(jīng)足夠簡(jiǎn)單,Unity開(kāi)發(fā)者在選取技術(shù)的時(shí)候直接使用即可。

?

Unity的序列化與反序列化技術(shù)方案

?

網(wǎng)絡(luò)發(fā)送的都是數(shù)據(jù)字節(jié)流,Unity與服務(wù)端通訊要把要發(fā)送的數(shù)據(jù)對(duì)象變成二進(jìn)制字節(jié)流,然后通過(guò)網(wǎng)絡(luò)傳送出去,收到字節(jié)流以后,又要重建回?cái)?shù)據(jù)對(duì)象,完成數(shù)據(jù)發(fā)送。數(shù)據(jù)對(duì)象變成二進(jìn)制字節(jié)流這個(gè)過(guò)程叫序列化,把二進(jìn)制字節(jié)流轉(zhuǎn)回?cái)?shù)據(jù)對(duì)象叫反序列化。

序列化/反序列化目前主要有兩個(gè)打的方向:一個(gè)是二進(jìn)制序列化,一個(gè)是文本序列化;

二進(jìn)制序列化/反序列化:基于二進(jìn)制的bit,通過(guò)用戶商量的協(xié)議來(lái)把數(shù)據(jù)對(duì)象變成二進(jìn)制bit數(shù)據(jù)流,反序列化的時(shí)候根據(jù)用戶協(xié)議,來(lái)把bit數(shù)據(jù)流變成數(shù)據(jù)對(duì)象。

文本序列化: 將數(shù)據(jù)變成人眼可讀的文本數(shù)據(jù)。當(dāng)收到序列化好的文本數(shù)據(jù)的時(shí)候,根據(jù)文本數(shù)據(jù)的規(guī)則來(lái)解析出里面的數(shù)據(jù)重建數(shù)據(jù)對(duì)象。

二進(jìn)制序列化/反序列化: 我們把一些基本的數(shù)據(jù)類型用bit來(lái)進(jìn)行編碼,如 int, float, string bool等。寫(xiě)好這些基本數(shù)據(jù)類型的編碼和解碼的代碼, 然后編寫(xiě)要數(shù)據(jù)對(duì)象的協(xié)議,然后開(kāi)發(fā)一個(gè)編譯器,他可以根據(jù)這個(gè)協(xié)議文件,基于基本數(shù)據(jù)類型的編碼/解碼函數(shù),根據(jù)協(xié)議,結(jié)合基本數(shù)據(jù)類型的編碼解碼,按照對(duì)象的結(jié)構(gòu),拆分成若干基本數(shù)據(jù)類型,自動(dòng)生成編碼/解碼函數(shù)代碼。

文本序列化的解決方案: json, xml等;

二進(jìn)制序列化/反序列化解決方案: protobuf;

?

TCP的封包與拆包

?

上面講解了,應(yīng)用層的數(shù)據(jù)包有可能被拆分成若干”TCP數(shù)據(jù)包”,還有可能兩個(gè)應(yīng)用層的數(shù)據(jù)包連在一起在一個(gè)”TCP數(shù)據(jù)包”中。為了收數(shù)據(jù)的時(shí)候能完整正確的收到應(yīng)用層的數(shù)據(jù)包,我們必須要把兩個(gè)應(yīng)用層的數(shù)據(jù)報(bào)之間做好分隔標(biāo)記,當(dāng)我們收到數(shù)據(jù)以后就可以根據(jù)分隔標(biāo)記來(lái)決定哪些數(shù)據(jù)是哪個(gè)包的。目前有兩種做法:

(1) 大小+數(shù)據(jù)內(nèi)容+校驗(yàn)碼模式;[size][數(shù)據(jù)body][校驗(yàn)], 游戲開(kāi)發(fā)中經(jīng)常會(huì)使用這種方式來(lái)做封包, 收數(shù)據(jù)的時(shí)候,根據(jù)大小來(lái)將數(shù)據(jù)包完整的組合出來(lái)。WebSocket也是采用的這種方式。

(2) 特定的分割符模式: 123456\r\n67890, Html采用特定的分割符號(hào)來(lái)拆分?jǐn)?shù)據(jù)內(nèi)容。

?

基于http的短連接技術(shù)方案

短連接,前面?zhèn)€講過(guò)的,用完就斷開(kāi)連接,下次要用的時(shí)候再重新的連接。短連接是使用TCP Socket策略,而這種策略最常用的就是http(基于TCP Socket+http超文本傳輸協(xié)議)。

Unity網(wǎng)絡(luò)框架中也要使用http,主要是和服務(wù)器對(duì)接基于http通訊以及資源服務(wù)器的下載等需求。Unity作為客戶端,要使用http,都已經(jīng)封裝好了UnityWebRequest,同時(shí)UnityWebRequest是多線程模式,可以同時(shí)并發(fā)N個(gè)請(qǐng)求。

?

Unity?網(wǎng)絡(luò)框架設(shè)計(jì)與實(shí)現(xiàn)原理

?

鋪墊了這么多,我們直接來(lái)上Unity網(wǎng)絡(luò)框架的架構(gòu)設(shè)計(jì)結(jié)構(gòu)圖,供大家參考。

?

這里接收數(shù)據(jù)的時(shí)候,采用多線程來(lái)做,收到數(shù)據(jù)后,進(jìn)行拆包與反序列化,得到數(shù)據(jù)對(duì)象后,放事件隊(duì)列,游戲主線程從事件隊(duì)列里面獲取網(wǎng)絡(luò)事件,然后進(jìn)行處理。發(fā)送數(shù)據(jù)出去的時(shí)候,我們?cè)谟螒蛑骶€程調(diào)用異步的網(wǎng)絡(luò)Send函數(shù),避免IO阻塞。注意好這些點(diǎn),就可以設(shè)計(jì)出一個(gè)很好的網(wǎng)絡(luò)框架。

?

本節(jié)分享就到這里了,關(guān)注我,學(xué)習(xí)更多的Unity框架設(shè)計(jì)的技巧。

附:視頻教學(xué)

https://www.bycwedu.com/promotion_channels/2146264125

Unity框架設(shè)計(jì)系列專題:如何設(shè)計(jì)網(wǎng)絡(luò)框架的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
烟台市| 仪陇县| 晋中市| 秭归县| 临夏县| 城口县| 遂川县| 稻城县| 乌苏市| 景泰县| 冷水江市| 富顺县| 方山县| 黔西县| 清流县| 肇源县| 民乐县| 新郑市| 双辽市| 四平市| 彰化县| 台中县| 通州市| 迁安市| 廊坊市| 会理县| 五寨县| 江安县| 本溪| 平邑县| 和林格尔县| 天津市| 长沙市| 许昌市| 深水埗区| 保亭| 贡嘎县| 绥化市| 敦化市| 科尔| 英德市|