• <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>

            3d Game Walkman

            3d圖形渲染,網(wǎng)絡(luò)引擎 — tonykee's Blog
            隨筆 - 45, 文章 - 0, 評(píng)論 - 309, 引用 - 0
            數(shù)據(jù)加載中……

            今天做了一個(gè)Struct結(jié)構(gòu),作為游戲里面的包容器來(lái)使用,可以一次發(fā)送多個(gè)邏輯結(jié)構(gòu)信息了,爽啊!!!

            游戲里面的數(shù)據(jù),最重要的就是如何組織,常見的包結(jié)構(gòu)就是type+len+data這樣的結(jié)構(gòu) 

            //所有包的基類型
            struct BasePack
             {
              unsigned short type;  //類型
              unsigned short len;   //長(zhǎng)度
              BasePack();
              unsigned short size();
             };


             //////////////////////////////////////////////////////////////////////////
             //比如這個(gè)是登錄包結(jié)構(gòu)
             struct LoginPack :public BasePack
             {
              char username[15];
              char password[10];
              LoginPack();
              unsigned short size();
             };

            //..還有很多類型的包結(jié)構(gòu),自己去擴(kuò)展

            //下面這個(gè)包結(jié)構(gòu)就很特別了:
            這個(gè)struct 結(jié)構(gòu)能保存變長(zhǎng)的子結(jié)構(gòu)體,也就是結(jié)構(gòu)體的容器,如果一次要發(fā)送大量查詢的數(shù)據(jù),可以用這個(gè)容器來(lái)裝載。結(jié)構(gòu)大致如下:
            //////////////////////////////////////////////////////////////////////////
             //集合包,這是個(gè)很特殊的包,里面的數(shù)據(jù)是變長(zhǎng)的(buffer 將作為子包的首指針)
             //當(dāng)然也有個(gè)上限,只不過(guò)和StringPack一樣,每次發(fā)送的數(shù)據(jù)量不固定,并不一定是包體的長(zhǎng)度,
             //使用這個(gè)包的注意事項(xiàng):1.如果用tcp,總長(zhǎng)不要超過(guò)4096, 如果用udp總長(zhǎng)不要超過(guò)1024(安全指數(shù))
             //                      2.一般一個(gè)包不會(huì)共享給多個(gè)線程來(lái)處理,而且都是臨時(shí)拼發(fā),并未考慮線程安全
             struct CollectionPack:public BasePack
             {
              unsigned short mSubPackCount;   //子包的數(shù)量

              char buffer[4096];           //最大限度的包長(zhǎng)度,做緩沖

              CollectionPack();

              //清除CollectionPack里面的內(nèi)容
              void clear();

              //得到子包的數(shù)量
              unsigned short getSubpackCount();

              //添加子包,添加是否成功,集合包的大小,默認(rèn)不超過(guò)MTU的大小,當(dāng)然如果是TCP傳輸,則沒(méi)有這個(gè)限制,最大可以是4096
              bool   append(BasePack &pack,  unsigned short  maxsize=1500);

              //本集合包的總長(zhǎng)度
              unsigned short size();

              //重載數(shù)組運(yùn)算符,這樣就可以數(shù)組迭代的方式訪問(wèn)子包了,不過(guò)用索引迭代沒(méi)有next迭代的效率高
              BasePack *operator[](int idx);

              //p迭代的指針,返回當(dāng)前取出來(lái)的包的指針使用方法如下:
              //   BasePack *p = 0;
              //while(collection.next(&p))
              //{
              //  p就是當(dāng)前你找到的包了
              //}
              BasePack * next(BasePack ** p);
             };


            CollectionPack::CollectionPack()
            {
             memset(buffer,0, 4096);
             type = COLLECTION_PACK;
             mSubPackCount = 0;
            }


            //清除CollectionPack里面的內(nèi)容
            void CollectionPack::clear()
            {
             mSubPackCount = 0;
             memset(buffer,0, 4096);
            }

            //得到子包的數(shù)量
            unsigned short CollectionPack::getSubpackCount()
            {
             return mSubPackCount;
            }

             

            //添加子包,添加是否成功
            bool   CollectionPack::append(BasePack &pack, unsigned short maxsize)
            {
             unsigned int currentlen = size(); //當(dāng)前整個(gè)包的長(zhǎng)度
             unsigned int psize = pack.size(); //即將要加入的包的長(zhǎng)度

             if(psize + currentlen > maxsize || psize + currentlen > SESSION_BUFFER_LONGTH)
             {
              return false; //不能夠再裝了
             }

             int len  = size() - 6;

             memcpy(buffer + len, &pack,  pack.size());

             //StringPack *p = (StringPack *) (buffer + len);
             mSubPackCount ++;
             return true;
            }


            //本集合包的總長(zhǎng)度
            unsigned short CollectionPack::size()
            {
             len = 0;
             for(unsigned short i = 0; i < mSubPackCount; i ++)
             {
              BasePack * p = (BasePack *) (buffer + len);
              len += p->size();
             }
             len += 6;     //(type len  SubPackNum 共6個(gè)字節(jié))
             return len;
            }

             

            //重載數(shù)組運(yùn)算符,這樣就可以數(shù)組迭代的方式訪問(wèn)子包了,不過(guò)用索引迭代沒(méi)有next迭代的效率高
            BasePack * CollectionPack::operator[](int idx)
            {
             if(idx < 0 || idx >=mSubPackCount)
             {
              return 0; //下標(biāo)越界
             }

             int ln = 0;
             for(unsigned short i = 0; i < mSubPackCount; i ++)
             {
              BasePack * p = (BasePack *) (buffer + ln);

              if(idx == i)
               return p;
              else
               ln += p->size();
             }

             return 0;
            }

             


            //p迭代的指針,返回當(dāng)前取出來(lái)的包的指針使用方法如下:
            //   BasePack *p = 0;
            //while(collection.next(&p))
            //{
            //  p就是當(dāng)前你找到的包了
            //}
            BasePack *  CollectionPack::next(BasePack ** p)
            {
             char *cur = 0;

             if((*p)==0)
              cur = buffer;
             else
              cur = (char *)(*p);

             //指針后移,定位到下一個(gè)包的位置
             (*p)=(BasePack *)(cur + ((BasePack *)cur)->size());

             if((*p)->type == 0)
              return 0; //沒(méi)有類型為0類型的包,如果為0,顯然是到末尾了
             else
              return (*p);
            }


            有了以上這個(gè)容器,要把一些小包組合起來(lái)一起發(fā)送就非常方便了,但是組合的時(shí)候,還是要考慮不能超出上限范圍的

            不過(guò)在真實(shí)的游戲服務(wù)器里面,包不一定是采用結(jié)構(gòu)體的方式來(lái)發(fā)送的,有的是把對(duì)象串行化成為字節(jié)流的方式來(lái)發(fā)送。
            我覺(jué)得這樣比較麻煩,要encoding decoding,效率調(diào)試都不方便,直接法結(jié)構(gòu)體,高效,簡(jiǎn)單,可就是不太安全。

            posted on 2008-01-24 00:21 李侃 閱讀(2052) 評(píng)論(2)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)模塊

            評(píng)論

            # re: 今天做了一個(gè)Struct結(jié)構(gòu),作為游戲里面的包容器來(lái)使用,可以一次發(fā)送多個(gè)邏輯結(jié)構(gòu)信息了,爽啊!!!  回復(fù)  更多評(píng)論   

            直接序列化數(shù)據(jù)嘛,干嘛那么麻煩
            2008-01-24 08:50 | teli

            # re: 今天做了一個(gè)Struct結(jié)構(gòu),作為游戲里面的包容器來(lái)使用,可以一次發(fā)送多個(gè)邏輯結(jié)構(gòu)信息了,爽啊!!!  回復(fù)  更多評(píng)論   

            提個(gè)建議,不要用摘要方式發(fā)文吧?每看一篇文章都要點(diǎn)擊鏈接進(jìn)來(lái),不方便。
            2008-01-25 09:27 | Fox
            亚洲中文字幕久久精品无码APP| 久久精品国产精品亚洲毛片| 久久福利青草精品资源站免费| 色天使久久综合网天天| 久久久精品日本一区二区三区| 久久综合狠狠综合久久激情 | 久久综合久久综合久久综合| 久久精品国产亚洲欧美| 久久久久夜夜夜精品国产| 99久久国产综合精品成人影院| 久久免费高清视频| 久久无码国产| 久久精品中文字幕大胸| 久久AV高潮AV无码AV| 国产亚洲精品美女久久久| 久久精品一区二区三区不卡| 久久香蕉一级毛片| 四虎久久影院| 久久A级毛片免费观看| 99精品伊人久久久大香线蕉| 久久久久国色AV免费看图片| 中文字幕无码久久久| 久久久女人与动物群交毛片| 久久精品国产91久久综合麻豆自制 | 激情久久久久久久久久| 久久精品夜色噜噜亚洲A∨| 一本色道久久综合狠狠躁篇| 久久精品国产亚洲AV久| 国产精品久久久久aaaa| 午夜精品久久久久久| 久久99精品久久久久久动态图| 国内精品久久久久久久coent| 久久久无码精品亚洲日韩蜜臀浪潮| 人妻精品久久久久中文字幕一冢本| 国产精品久久久久久| 国产香蕉久久精品综合网| 国内精品久久久久久野外| 免费精品久久天干天干| 国产精品99久久不卡| 亚洲精品tv久久久久久久久| 国产成人久久777777|