• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調(diào)做技術(shù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

            WoW服務(wù)器模擬器Ascent網(wǎng)絡(luò)模塊分析

            Ascent網(wǎng)絡(luò)模塊

            Author: Kevin Lynx

             

            Ascent是WoW的服務(wù)器模擬器,你可以從它的SVN上獲取它的全部代碼,并從它的WIKI頁(yè)面獲取架構(gòu)起整個(gè)服務(wù)器的相關(guān)步驟。

            基本架構(gòu):

            Ascent網(wǎng)絡(luò)模塊核心的幾個(gè)類(lèi)關(guān)系如下圖所示:


            ThreadBase屬于Ascent線程池模塊中的類(lèi),它實(shí)現(xiàn)了一個(gè)job類(lèi),當(dāng)其被加入到線程池中開(kāi)始執(zhí)行時(shí),線程池管理器會(huì)為其分配一個(gè)線程(如果有線程資源)并多態(tài)調(diào)用到ThreadBase派生類(lèi)的run函數(shù)。

            SocketWorkerThread用以代表IOCP網(wǎng)絡(luò)模型中的一個(gè)工作者線程,它會(huì)從IOCP結(jié)果隊(duì)列里取出異步IO的操作結(jié)果。這里的IOCP使用的完成鍵是Socket對(duì)象指針。SocketWorkerThread獲取到IO操作結(jié)果后,根據(jù)獲得的完成鍵將結(jié)果通知給具體的Socket對(duì)象。(Socket的說(shuō)明見(jiàn)后面)

            ListenSocket代表一個(gè)監(jiān)聽(tīng)套接字。該網(wǎng)絡(luò)模塊其實(shí)只是簡(jiǎn)單地將socket中的概念加以封裝。也就說(shuō),它依然把一個(gè)套接字分為兩種類(lèi)型:監(jiān)聽(tīng)套接字和數(shù)據(jù)套接字(代表一個(gè)網(wǎng)絡(luò)連接)。所謂的監(jiān)聽(tīng)套接字,是指只可以在該套接字上進(jìn)行監(jiān)聽(tīng)操作;而數(shù)據(jù)套接字則只可以在此套接字上進(jìn)行發(fā)送、接收數(shù)據(jù)的操作。

            Socket代表我上面說(shuō)的數(shù)據(jù)套接字。ListenSocket是一個(gè)類(lèi)模板,為這個(gè)模板指定的模板參數(shù)通常是派生于Socket的類(lèi)。其實(shí)這里使用了這個(gè)小技巧隱藏了工廠模式的細(xì)節(jié)。因?yàn)長(zhǎng)istenSocket被放在一個(gè)單獨(dú)的線程里運(yùn)作,當(dāng)其接受到一個(gè)新的網(wǎng)絡(luò)連接時(shí),就創(chuàng)建一個(gè)Socket派生類(lèi)對(duì)象。(ListenSocket類(lèi)如何知道這個(gè)派生類(lèi)的類(lèi)名?這就是通過(guò)類(lèi)模板的那個(gè)模板參數(shù))

            上層模塊通常會(huì)派生Socket類(lèi),實(shí)現(xiàn)一些IO操作的回調(diào)。也就說(shuō),當(dāng)某個(gè)IO操作完成后,會(huì)通過(guò)Socket基類(lèi)讓上層模塊獲取通知。

            SocketMgr是一個(gè)全局單件類(lèi)。它主要負(fù)責(zé)一些網(wǎng)絡(luò)庫(kù)的全局操作(例如winsock庫(kù)的初始化),它還維護(hù)了一個(gè)容器,保存所有的Socket對(duì)象。這其實(shí)是它的主要作用。

            運(yùn)作之一,接收新的連接

            接收新的網(wǎng)絡(luò)連接是通過(guò)ListenSocket實(shí)現(xiàn)的。在創(chuàng)建一個(gè)ListenSocket對(duì)象時(shí),你需要指定它的模板參數(shù)。這個(gè)參數(shù)通常是一個(gè)派生于Socket的類(lèi)。如下:

            ascent-logonserver/Main.cpp

                

            ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport);

             

            AuthSocket派生于Socket。創(chuàng)建ListenSocket時(shí)構(gòu)造函數(shù)指定監(jiān)聽(tīng)I(yíng)P和監(jiān)聽(tīng)端口。

             

            因?yàn)長(zhǎng)istenSocket派生于ThreadBase,屬于線程池job,因此要讓ListenSocket工作起來(lái),只需要將其加入到線程池管理器:

            ascent-logonserver/Main.cpp

             

            ThreadPool.ExecuteTask(cl);

             

            ListenSocket開(kāi)始運(yùn)作起來(lái)后,會(huì)阻塞式地WSAAccept。如果WSAAccept返回一個(gè)有效的套接字,ListenSocket就創(chuàng)建一個(gè)Socket派生類(lèi)對(duì)象(類(lèi)型由模板參數(shù)指定),在上面舉的例子中,也就是AuthSocket:

            ascent-logonserver/ ListenSocketWin32.h

                    

              socket = new T(aSocket); //創(chuàng)建AuthSocket并保存網(wǎng)絡(luò)套接字aSocket

                     socket
            ->SetCompletionPort(m_cp);//保存完成端口對(duì)象

                     socket
            ->Accept(&m_tempAddress); //關(guān)聯(lián)到完成端口等

            Accept函數(shù)最終會(huì)將新創(chuàng)建的Socket對(duì)象保存到SocketMgr對(duì)象內(nèi)部維護(hù)的容器里。在這里,還會(huì)回調(diào)到上層模塊的OnConnect函數(shù),從而實(shí)現(xiàn)信息捕獲。

            運(yùn)作之二,接收數(shù)據(jù)

            在windows平臺(tái)下,該網(wǎng)絡(luò)模塊使用的是IOCP模型,屬于異步IO。當(dāng)接收新的連接時(shí),即發(fā)出WSARecv的IO操作。在工作者線程中,也就是SocketWorkerThread中,會(huì)根據(jù)IOCP完成鍵得到Socket對(duì)象指針,然后根據(jù)不同的IO操作結(jié)果多態(tài)回調(diào)到Socket派生類(lèi)對(duì)應(yīng)的函數(shù)。例如如果是WSARecv完成,則調(diào)用到AuthSocket::OnRead函數(shù)(上述例子)。OnRead函數(shù)直接可以獲取到保存數(shù)據(jù)的緩沖區(qū)指針。事實(shí)上,每一個(gè)Socket對(duì)象在被創(chuàng)建時(shí),就會(huì)自動(dòng)創(chuàng)建接收緩沖區(qū)以及發(fā)送緩沖區(qū)。

            運(yùn)作之三,發(fā)送數(shù)據(jù)

            分析到這里,我們可以看出,該網(wǎng)絡(luò)模塊實(shí)現(xiàn)得很一般。在接受數(shù)據(jù)部分,網(wǎng)絡(luò)工作者線程回調(diào)到對(duì)應(yīng)的Socket對(duì)象,Socket直接對(duì)數(shù)據(jù)進(jìn)行上層邏輯處理。更好的做法是當(dāng)工作者線程回調(diào)到上層Socket(Socket的派生類(lèi))時(shí),這里應(yīng)該簡(jiǎn)單地將數(shù)據(jù)組織成上層數(shù)據(jù)包并放入上層數(shù)據(jù)包隊(duì)列,讓上層邏輯稍后處理,而不是讓網(wǎng)絡(luò)模塊自己去處理。這樣做主要是考慮到多線程模型。

            同樣,該網(wǎng)絡(luò)模塊的發(fā)送模塊也是一樣,沒(méi)有緩沖機(jī)制。當(dāng)要發(fā)送數(shù)據(jù)時(shí),直接調(diào)用到Socket的Send函數(shù)。該函數(shù)拷貝用戶(hù)數(shù)據(jù)到自己維護(hù)的發(fā)送緩沖區(qū),然后將自己的緩沖區(qū)指針直接提交給IOCP,WSASend發(fā)送。

             

            結(jié)束

            該網(wǎng)絡(luò)模塊實(shí)現(xiàn)的似乎有點(diǎn)簡(jiǎn)陋,在該模塊之上也沒(méi)有數(shù)據(jù)校驗(yàn)、數(shù)據(jù)加密的模塊(這些動(dòng)作散亂地分布在最上層邏輯)。在架構(gòu)上也沒(méi)能很好地將概念區(qū)分開(kāi)來(lái),Socket套用了原始socket中的數(shù)據(jù)套接字,而不是我所希望的NetSession。可以圈點(diǎn)的地方在于該模塊很多地方使用了回調(diào)函數(shù)表,從而方便地實(shí)現(xiàn)事件傳送。

             

            posted on 2008-04-02 21:22 Kevin Lynx 閱讀(4448) 評(píng)論(4)  編輯 收藏 引用 所屬分類(lèi): game develop

            評(píng)論

            # re: WoW服務(wù)器模擬器Ascent網(wǎng)絡(luò)模塊分析 2008-04-11 13:47 Bugs

            已閱  回復(fù)  更多評(píng)論   

            # re: WoW服務(wù)器模擬器Ascent網(wǎng)絡(luò)模塊分析 2008-07-21 21:41 是是

            海星  回復(fù)  更多評(píng)論   

            # re: WoW服務(wù)器模擬器Ascent網(wǎng)絡(luò)模塊分析 2010-06-23 11:25 游客

            ascent代碼還能獲取嗎?
            請(qǐng)問(wèn)svn地址?  回復(fù)  更多評(píng)論   

            # re: WoW服務(wù)器模擬器Ascent網(wǎng)絡(luò)模塊分析[未登錄](méi) 2011-03-11 16:48 BERT

            “我們可以看出,該網(wǎng)絡(luò)模塊實(shí)現(xiàn)得很一般。在接受數(shù)據(jù)部分,網(wǎng)絡(luò)工作者線程回調(diào)到對(duì)應(yīng)的Socket對(duì)象,Socket直接對(duì)數(shù)據(jù)進(jìn)行上層邏輯處理。”

            博主沒(méi)仔細(xì)看吧?
            虛函數(shù)OnRead做了解包,將數(shù)據(jù)組織成上層數(shù)據(jù)包并放入上層數(shù)據(jù)包隊(duì)列,讓上層邏輯稍后處理  回復(fù)  更多評(píng)論   

            久久99精品久久久久久动态图| 久久精品国产精品青草| 亚洲午夜精品久久久久久浪潮 | 久久精品一区二区三区不卡| 久久精品亚洲乱码伦伦中文| 狠狠色丁香久久婷婷综| 人人狠狠综合88综合久久| 久久久久亚洲AV无码专区桃色| 狠狠色丁香婷婷综合久久来| 欧美激情精品久久久久久久九九九| 久久精品国产亚洲av日韩| 久久亚洲中文字幕精品有坂深雪| 婷婷久久久亚洲欧洲日产国码AV| 久久久久久伊人高潮影院| 一本大道久久东京热无码AV| 久久er热视频在这里精品| 亚洲日韩中文无码久久| 人人狠狠综合久久88成人| 亚洲国产成人精品女人久久久 | 亚洲综合日韩久久成人AV| 国产亚洲精久久久久久无码AV| 国产精品伊人久久伊人电影| 久久精品无码专区免费| 狠狠色丁香久久综合五月| 久久精品国产亚洲AV无码偷窥| 久久久久久久久波多野高潮| 久久九色综合九色99伊人| 国产一级持黄大片99久久| 久久久久亚洲av无码专区| 久久夜色精品国产噜噜麻豆| 亚洲αv久久久噜噜噜噜噜| 久久国产AVJUST麻豆| 亚洲国产精品无码久久久久久曰| 国产成人精品久久一区二区三区av| 国产亚洲美女精品久久久久狼| 久久99久久99精品免视看动漫| 亚洲成色WWW久久网站| 激情伊人五月天久久综合| avtt天堂网久久精品| 狠狠狠色丁香婷婷综合久久五月 | 久久精品国产影库免费看|