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

            我的玻璃盒子

            (轉(zhuǎn)載)一個(gè)struct結(jié)構(gòu),一次發(fā)送多個(gè)邏輯結(jié)構(gòu)信息

            原文:http://www.shnenglu.com/tonykee/archive/2008/01/24/41766.html

            游戲里面的數(shù)據(jù),最重要的就是如何組織,常見的包結(jié)構(gòu)就是type+len+data這樣的結(jié)構(gòu)
            //所有包的基類型
            struct BasePack
            {
              unsigned short type;  //類型
              unsigned short len;   //長度
              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)能保存變長的子結(jié)構(gòu)體,也就是結(jié)構(gòu)體的容器,如果一次要發(fā)送大量查詢的數(shù)據(jù),可以用這個(gè)容器來裝載。結(jié)構(gòu)大致如下:
            //////////////////////////////////////////////////////////////////////////
            //集合包,這是個(gè)很特殊的包,里面的數(shù)據(jù)是變長的(buffer 將作為子包的首指針)
            //當(dāng)然也有個(gè)上限,只不過和StringPack一樣,每次發(fā)送的數(shù)據(jù)量不固定,并不一定是包體的長度,
            //使用這個(gè)包的注意事項(xiàng):1.如果用tcp,總長不要超過4096, 如果用udp總長不要超過1024(安全指數(shù))
            //                      2.一般一個(gè)包不會共享給多個(gè)線程來處理,而且都是臨時(shí)拼發(fā),并未考慮線程安全
            struct CollectionPack:public BasePack
            {
              unsigned short mSubPackCount;   //子包的數(shù)量

              char buffer[4096];           //最大限度的包長度,做緩沖

              CollectionPack();

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

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

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

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

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

              //p迭代的指針,返回當(dāng)前取出來的包的指針使用方法如下:
              //   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è)包的長度
            unsigned int psize = pack.size(); //即將要加入的包的長度

            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;
            }

            //本集合包的總長度
            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ù)組迭代的方式訪問子包了,不過用索引迭代沒有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)前取出來的包的指針使用方法如下:
            //   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; //沒有類型為0類型的包,如果為0,顯然是到末尾了
            else
              return (*p);
            }

            有了以上這個(gè)容器,要把一些小包組合起來一起發(fā)送就非常方便了,但是組合的時(shí)候,還是要考慮不能超出上限范圍的
            不過在真實(shí)的游戲服務(wù)器里面,包不一定是采用結(jié)構(gòu)體的方式來發(fā)送的,有的是把對象串行化成為字節(jié)流的方式來發(fā)送。
            我覺得這樣比較麻煩,要encoding decoding,效率調(diào)試都不方便,直接法結(jié)構(gòu)體,高效,簡單,可就是不太安全。

            posted on 2008-01-24 16:28 深藍(lán)色系統(tǒng) 閱讀(207) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            <2009年8月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            統(tǒng)計(jì)

            常用鏈接

            留言簿(75)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久免费精品一区二区| 99久久99久久精品国产片| 亚洲人成电影网站久久| 久久综合久久综合亚洲| 亚洲国产另类久久久精品 | 久久人妻AV中文字幕| 久久久久亚洲AV片无码下载蜜桃| 99久久中文字幕| 久久天天躁狠狠躁夜夜2020老熟妇| 色诱久久av| 久久99国产精品久久久| 怡红院日本一道日本久久 | 久久国产精品免费一区| 久久午夜福利电影| 久久国产精品99国产精| 精品久久久久久无码人妻蜜桃| 一个色综合久久| 91久久婷婷国产综合精品青草| 久久久国产一区二区三区| 青草国产精品久久久久久| 久久精品无码午夜福利理论片| 88久久精品无码一区二区毛片| 国产精品久久久久免费a∨| 久久夜色精品国产噜噜麻豆| 91精品国产91久久| 久久精品国产第一区二区三区| 久久精品国产第一区二区| 久久婷婷五月综合色高清| 久久综合伊人77777麻豆| 色综合久久88色综合天天| 日产精品久久久久久久性色| 人妻中文久久久久| 99久久人人爽亚洲精品美女| 99久久超碰中文字幕伊人| 久久久噜噜噜www成人网| 国产成人精品综合久久久| 人妻无码久久精品| 久久天天躁夜夜躁狠狠| 久久亚洲精品无码aⅴ大香| 亚洲一区精品伊人久久伊人| 久久精品国产亚洲av瑜伽|