﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-关中刀客</title><link>http://www.cppblog.com/guanzhongdaoke/</link><description>致力于cobra系列模块的设计与开发</description><language>zh-cn</language><lastBuildDate>Wed, 08 Apr 2026 01:43:19 GMT</lastBuildDate><pubDate>Wed, 08 Apr 2026 01:43:19 GMT</pubDate><ttl>60</ttl><item><title>基于cobra_win实现上层游戏服务器</title><link>http://www.cppblog.com/guanzhongdaoke/archive/2008/10/05/63276.html</link><dc:creator>关中刀客</dc:creator><author>关中刀客</author><pubDate>Sun, 05 Oct 2008 08:26:00 GMT</pubDate><guid>http://www.cppblog.com/guanzhongdaoke/archive/2008/10/05/63276.html</guid><wfw:comment>http://www.cppblog.com/guanzhongdaoke/comments/63276.html</wfw:comment><comments>http://www.cppblog.com/guanzhongdaoke/archive/2008/10/05/63276.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/guanzhongdaoke/comments/commentRss/63276.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guanzhongdaoke/services/trackbacks/63276.html</trackback:ping><description><![CDATA[&nbsp;
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span>基于</span></strong><strong><span>cobra_win</span></strong><strong><span>实现游戏上层服务器</span></strong><strong></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span>&nbsp;-----------</span><strong><span>关中刀客</span></strong><strong></strong></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span>&nbsp;-----------</span><st1:chsdate w:st="on" IsROCDate="False" IsLunarDate="False" Day="07" Month="09" Year="2008"><strong><span>2008</span></strong><strong><span>年</span></strong><strong><span>09</span></strong><strong><span>月</span></strong><strong><span>07</span></strong><strong><span>日</span></strong></st1:chsdate><strong></strong></p>
<p><span>cobra_win</span><span>是基于</span><span>windows</span><span>操作系统，使用</span><span>IOCP</span><span>技术，开发的一套网络底层通讯库。该库现在已经拥有一套完整可配置的内存管理容器，并且拥有强大的日志管理系统，线程类，仿</span><span>linux</span><span>内核实现的定时器管理器，以及</span><span>IOCP</span><span>相关的各种事件处理。</span><span>cobra_win</span><span>可为</span><span>IM</span><span>通讯软件，游戏服务器等提供强大的底层网络通讯库支持。</span></p>
<p><span>cobra_win</span><span>采用</span><span>XML</span><span>语言作为配置文件，并使用著名的开源库</span><span>tinyxml</span><span>来对其进行解析，使用者在使用</span><span>cobra_win</span><span>进行开发的时候，只需要仅仅根据自己开发的项目设置相关的参数即可，无需改动</span><span>cobra_win</span><span>内部数据和模块。对于多线程环境中，为了保证关键数据区域的串行化操作，通常都是采用线程锁的方式，对于</span><span>cobra_win</span><span>的诸多内存管理器，使用者在使用时，可以根据自己的开发需要，定制是否为线程安全的内存容器，这样子对于容器的串行化操作，该容器内部会自动的进行加锁解锁，而不必在外层频繁的调用，极大地减轻了问题的产生频率。一个强大的日志管理系统，是一个项目成败的关键，对于我们的服务器程序来说，需要大量记录日志来记录各个阶段的关键信息，</span><span>cobra_win</span><span>的日志管理器，仿照</span><span>java</span><span>的</span><span>log4cxx</span><span>日志开源库，并进行了相关的精简，实现了可配置，分等级的日志管理器，并且考虑到效率的问题，</span><span>cobra_win</span><span>内部使用单独的线程来进行日志的纪录，在多核平台上，极大地提高了效率。考虑到一般网络游戏服务器的定时器定位在毫秒级别，我们吸收了</span><span>linux</span><span>源代码中定时器的实现机制，</span><span>cobra_win</span><span>实现了&#8220;双级缓冲，一级定长数组缓冲，二级双向链表缓冲&#8221;的策略，实现了对于毫秒级别的定时器管理机制</span><span>,</span><span>。</span></p>
<p><span>对于在使用</span><span>IOCP</span><span>开发网络服务器时出现的诸多问题，</span><span>cobra_win</span><span>都进行了合理的解决。首先，对于&#8220;死连接&#8221;问题，</span><span>cobra_win</span><span>在底层中，使用单独的线程来定时轮训所有连接，察看其连接的状态，如在规定的时间内没有进行数据收发，则超时并强制的关闭。在此，对于&#8220;</span><span>IOCP</span><span>发送大量数据导致没有可用缓冲区&#8221;的问题，在我们的</span><span>cobra_win</span><span>设置中，为了避免这个问题，我们使用集中缓冲发送策略，将我们需要发送的所有数据，先存储到固定的地方，然后根据定时器来控制发送的时间。对于服务器程序来说，我们经常会面临不定长的数据包，所以</span><span>cobra_win</span><span>底层实现了压包器</span><span>EPacket</span><span>和解包器</span><span>DPacket</span><span>来进行我们不定长数据的合并和拆分，极大地减轻了逻辑层面的设计复杂度。</span><span>cobra_win</span><span>已经将</span><span>IOCP</span><span>将要产生的各种事件单独的拆分出来，开发者只需要简单的继承自我们的</span><span>IIOThread</span><span>纯虚基类，然后实现相关完成事件的处理即可，不需要考虑底层的诸多实现细节，有利于节省开发时间，缩短开发周期，提高开发效率。对于异步多线程的使用，我们往往采用之间缓冲队列的方式，将底层</span><span>IO</span><span>多线程受到的数据，发送给上层逻辑线程的进行处理，但是，如果底层</span><span>IO</span><span>多线程的收包速度远远超过我们的逻辑线程处理能力的话，就会导致中间缓冲队列&#8220;爆炸&#8221;的情形，对于这个问题，</span><span>cobra_win</span><span>在设计的时候，采用&#8220;双缓冲安全队列&#8221;的方式，合理高效的避免了此种问题，使得服务器程序按照&#8220;流水线&#8221;的方式有效进行。</span></p>
<p><span>如何使用</span><span>cobra_win</span><span>开发上层服务器。本文将使用</span><span>cobra_win</span><span>，来实现一个完成的网络游戏登陆服务器框架。</span></p>
<p><span>首先，我们实现登陆服务器的服务器管理器类：</span></p>
<p align=left><span>/*</span></p>
<p align=left><span>* Copyright(c)2008</span></p>
<p align=left><span>*</span></p>
<p align=left><span>* </span><span>文件名称<span>: ServerMgr</span></span></p>
<p align=left><span>* </span><span>文件标识<span>:</span></span></p>
<p align=left><span>* </span><span>摘<span><span>&nbsp;&nbsp; </span></span>要 <span>: </span>登陆服务器管理器</span></p>
<p align=left><span>*</span></p>
<p align=left><span>* </span><span>当前版本<span>: cobra_login_server 0.03</span></span></p>
<p align=left><span>* </span><span>作<span><span>&nbsp;&nbsp; </span></span>者 <span>: </span>关中刀客</span></p>
<p align=left><span>* E-Mail&nbsp;: guanzhongdaoke@gmail.com</span></p>
<p align=left><span>* Blog<span>&nbsp;&nbsp;&nbsp; </span>: http://guan-zhong-dao-ke.blog.163.com/</span></p>
<p align=left><span>* </span><span>完成时间<span>: <st1:chsdate w:st="on" IsROCDate="False" IsLunarDate="False" Day="08" Month="09" Year="2008">2008<span><span>年09</span></span><span><span>月08</span></span><span><span>日</span></span></st1:chsdate></span></span></p>
<p align=left><span>*/</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>#include</span><span> <span>&lt;include/common/Header.h&gt;</span></span></p>
<p align=left><span>#include</span><span> <span>&lt;include/common/Singleton.h&gt;</span></span></p>
<p align=left><span>#include</span><span> <span>&lt;include/server/IOCPAcceptor.h&gt;</span></span></p>
<p align=left><span>#include</span><span> <span>&lt;include/server/IOCPConnector.h&gt;</span></span></p>
<p align=left><span>#include</span><span> <span>"DMsgList.h"</span></span></p>
<p align=left><span>#include</span><span> <span>"HeartBeatMgr.h"</span></span></p>
<p align=left><span>#include</span><span> <span>"IOSendMgr.h"</span></span></p>
<p align=left><span>#include</span><span> <span>&lt;vector&gt;</span></span></p>
<p align=left><span>using</span><span>&nbsp;<span>namespace</span>&nbsp;<span>cobra_win</span>;</span></p>
<p align=left>&nbsp;</p>
<p align=left>&nbsp;</p>
<p align=left><span>class</span><span>&nbsp;<span>ServerMgr</span> : <span>public</span> <span>Singleton</span>&lt;<span>ServerMgr</span>&gt;</span></p>
<p align=left><span>{</span></p>
<p align=left><span>private</span><span>:</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>bool</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_bRun</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>登陆服务器当前运行的状态</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>IOCPAcceptor</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_Acceptor</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>本地监听器</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>bool</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_bAcceptorState</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>本地监听器状态</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>IOCPConnector</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_MasterServerConnector</span>;&nbsp;<span>// </span></span><span>主控服务器连接器</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>bool</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_bMasterServerState</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>主控服务器状态</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>LOGINSERVER_CONFIG_INFO</span>&nbsp;<span>m_LoginServerCfg</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>登陆服务器的配置文件信息</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>IOSendMgr</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_IOSendMgr</span>; <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>// </span></span><span>集中数据缓冲发送管理器</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>HeartBeatMgr</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_HeartBeatMgr</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>心跳管理器</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>DMsgList</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_DMsgList</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>双重队列缓冲器</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span><span>std</span>::<span>vector</span>&lt;<span>SOCKET</span>&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>m_SocketList</span>;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>// </span></span><span>连接上来的客户端列表</span></p>
<p align=left><span>}</span><span>；</span></p>
<p align=left><span>对于我们的所有基于<span>cobra_win</span>的服务器来说，都需要建立一个相应的服务器管理器，里面包含诸多的元素，如上面的例子所示：首先，我们需要一个控制当前服务器状态的标志位<span>m_bRun;</span>然后就是本地监听器来负责接受所有的链接，下来就是必要的连接器，连接我们指定的<span>IP</span>地址和端口，还有一个必要的相应服务器专有配置文件，下来就是我们的&#8220;双重安全队列缓冲区&#8221;和&#8220;集中数据缓冲管理器&#8221;。这样子就构成了我们大体的服务器框架。详细的例子，我们参见我们的附件地址。</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>目前，我正在使用<span>cobra_win</span>来实现一整套的网络游戏服务器框架，在目前实现的诸多上层服务器，如登陆服务器，总控服务器，网关服务器，逻辑服务器，数据库服务器中，<span>cobra_win</span>的表现非常的优越，简单高效，不再去考虑诸多的底层问题，我们将精力全部的放在了上层逻辑的设计和实现上。 </span></p>
<p><span>cobra_win</span><span>在设计之初，奉承&#8220;简单，高效，实用&#8221;原则。同著名的</span><span>ACE</span><span>相比，</span><span>cobra_win</span><span>显得十分的短小精悍，由于</span><span>ACE</span><span>框架过于庞大，所以其对程序员的要求太过苛刻，并且</span><span>ACE</span><span>的庞大和过于完整导致其内部很多模块耦合性太高，不利于我们提炼出来单独使用，并且在使用</span><span>ACE</span><span>开发的过程中，一旦出现问题，程序员往往难以快速的定位出错的位置和原因，给我们的开发带来了诸多的不便。相比之下，</span><span>cobra_win</span><span>内部模块划分相对清晰简练，耦合性低，非常有利于拆分出来单独的使用，整体</span><span>cobra_win</span><span>对外接口简单明了，开发者可快速的上手并熟练使用，另外，由于</span><span>cobra_win</span><span>的简单清晰，短小精悍，也非常的有利于在此基础上进行更上层的扩展和开发。</span></p>
<p><span>关中刀客，游戏开发人员，目前专心致力于</span><span>cobra</span><span>系列模块的设计与开发，如果您对</span><span>cobra</span><span>系列模块感兴趣或者有更好的意见看法的话，</span><span><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#24744;&#21487;&#20197;&#36890;&#36807;&#103;&#117;&#97;&#110;&#122;&#104;&#111;&#110;&#103;&#100;&#97;&#111;&#107;&#101;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><span><span>您可以通过</span></span>guanzhongdaoke@gmail.com</a></span><span>或者访问</span><span><a href="http://guan-zhong-dao-ke.blog.163.com/">http://guan-zhong-dao-ke.blog.163.com/</a></span><span>与他联系。</span></p>
<img src ="http://www.cppblog.com/guanzhongdaoke/aggbug/63276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanzhongdaoke/" target="_blank">关中刀客</a> 2008-10-05 16:26 <a href="http://www.cppblog.com/guanzhongdaoke/archive/2008/10/05/63276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>~祝贺自己的blog开张~</title><link>http://www.cppblog.com/guanzhongdaoke/archive/2008/06/16/53599.html</link><dc:creator>关中刀客</dc:creator><author>关中刀客</author><pubDate>Mon, 16 Jun 2008 14:28:00 GMT</pubDate><guid>http://www.cppblog.com/guanzhongdaoke/archive/2008/06/16/53599.html</guid><wfw:comment>http://www.cppblog.com/guanzhongdaoke/comments/53599.html</wfw:comment><comments>http://www.cppblog.com/guanzhongdaoke/archive/2008/06/16/53599.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/guanzhongdaoke/comments/commentRss/53599.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guanzhongdaoke/services/trackbacks/53599.html</trackback:ping><description><![CDATA[虽然我有很多的blog<br>但是一直以来，还是保持每天看这个blog的习惯，学习了很多的东西，所以也申请了一个<br>希望以后能交些朋友，学些东西
<img src ="http://www.cppblog.com/guanzhongdaoke/aggbug/53599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanzhongdaoke/" target="_blank">关中刀客</a> 2008-06-16 22:28 <a href="http://www.cppblog.com/guanzhongdaoke/archive/2008/06/16/53599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>