怎么样使用VC++设计ActiveX控件

怎么样使用VC++设计ActiveX控件,第1张

ActiveX是Microsoft提出的一组使用COM(ComponentObjectModel,部件对象模型)使得软件部件在网络环境中进行交互的技术集。它与具体的编程语言无关。作为针对Internet应用开发的技术,ActiveX被广泛应用于WEB服务器以及客户端的各个方面。本文着重介绍以Visual C++ 50为工具,利用系统提供的AppWizard快速构造一个简单的ActiveX控件

通常VC++50提供两个途径开发ActiveX控制:MFC和ATL(ActiveXTemplateLibrary)。使用MFC,可以不必理会控制接口的细节,把注意力集中在控制本身的功能上,但是生成的控制比较大。而且,客户端如果要运行此ActiveX控制,必须拥有相应版本的MFC类库的DLL,否则,必须同时下载这些巨大的类库;使用ATL,由于不汲及MFC的标准类库,生成的控制相对较小,但开发者必须了解COM、OLE技术的细节。这里,我们主要说明一下使用MFC开发ActiveX控制的方法,因为这种方法相对比较容易。

在Microsoft Developer Studio环境下,按如下的操作步骤可以快速生成一个标准的ActiveX控件。首先,启动系统的AppWizard,用File菜单下的New菜单项创建新的项目。注意:我们选择的是列表框中的MFC ActiveX ControlWizard项。也可以使用ATL COM AppWizard项来产生ActiveX控件,这样实现的控件的最终代码量较小,但由于用这种方法加入的ActiveX控件对象从最基本的COM对象出发,故不能使用MFC类库中的COleControl所提供的强大功能。而用MFC ActiveX ControlWizard项则产生以COleControl为基类的控件对象类,它继承了所有COleControl类中实现的OLE控件的特性,包括窗口对象特性和方法、属性及事件等。接着,按照系统给出的提示信息逐步完成创建工作。用户可根据实际应用的要求定制控件的各项特性。

我们假定项目名为Test。创建工作完成后,打开Workspace文件Testdsw,可以看到系统生成的Test控件框架,主要的类及实现功能描述见下表:

派生类 基类 实现功能

CTestApp COleControlModule 控件实例的初始化和撤消

CTestCtrl COleControl 控件窗口的创建、更新及消息处理

CTestPropPage COlePropertyPage 控件属性页的设置及与实际属性值的交换

编译此项目,生成Testocx。在当前的Developer Studio环境下,这个控件已经被自动注册了。用系统提供的工具ActiveX Control Test Container可以立即进行测试,在已提供的可插入OLE控件列表中,Test Control就是我们生成的控件名。如果想在其它环境下使用它,则必须先对Testocx文件进行注册,具体做法是在命令行方式下键入命令:“regsvr32 …/Testocx”。此后,我们就可在任何支持ActiveX控件的环境中使用它了。注意:ocx文件应该随时更新和注册。

当然,这样生成的控件没有什么实质性的用处,若在任何一个包容器中测试它,则只可见一个矩形框和一个内切椭圆,除了缩放和位置移动功能外不能进行任何操作。

然而,我们希望开发出来的控件就像一个通常的编辑环境一样:用户可以在窗口内进行文本的输入和编辑,而且有工具条来支持各项操作。

1、为控件添加工具条和子窗口

VC++的模板常常是很有用的工具,我们设计一个类CToolbar,为控件类T添加工具条,显示每个按钮及提示信息。我们的控件类CtestCtrl是从这个类派生出来的,从而可为控件加上设计好了的工具条。

以下是实现工具条模板类的定义 (在Toolbarh文件中) :

template

class CToolbar

{

public:

CToolbar();

void CreateToolbar(HWND hParent);// 创建工具条

void AddButtons();// 逐个加入按钮

void DestroyToolbar();// 撤消工具条

LRESULT OnToolbarNeedText(WPARAM, LPNMHDR pnmh, BOOL&);

// 工具条上按钮的提示信息

protected:

HWND m_hwndToolbar;// 工具条的窗口句柄

};

接着,要对TestCtlh和TestCtlcpp作相应的修改。在TestCtlh中要先包含Toolbarh文件,并将控件类定义为:

class CTestCtrl : public COleControl, public CToolbar

然后,再加进消息映射宏:

BEGIN_TOOLBAR_MAP(CTestCtrl)

TOOLBAR_BUTTON(ID_New)

TOOLBAR_SEPARATOR()

TOOLBAR_BUTTON(ID_CUT)

TOOLBAR_SEPARATOR()

END_TOOLBAR_MAP()

以响应定制的工具条上的各个按钮消息。上面的宏在Toolbarh文件中被定义。于是,在CTestCtrl类的成员函数中就可以灵活使用CToolbar类的各项操作了。

另外,我们再为控件设计一个可编辑的子窗口。这实现起来很方便,在控件类定义中直接加入CEdit类的对象作为成员变量m_TestEdit即可。

要想真正生成我们自己的控件窗口,则需重载COleControl::CreateControlWindow函数。控件窗口被创建时,该函数被调用,函数中先调用基类同名函数,再依次调用CreateToolbar和CreateTestEdit 生成控件中的工具条和子窗口。自然,我们不再需要系统缺省调用的画图函数,将CTestCtrl::OnDraw 中画矩形框和椭圆的部分去掉。CreateToolbar在工具条模板类中实现;CreateTestEdit 在控件类中自定义,函数先计算控件窗口的客户区和工具条的窗口大小,得到子窗口的位置,使之填满控件中工具条以外的全部区域,然后调用m_TestEditCreate函数,设置参数使子窗口具有用户所希望的各项风格。

2、调整控件窗口中各个对象的位置

工具条和子窗口已经在控件中生成后,还有一项重要的工作就是当控件位置移动或大小改变时,要相应地调整工具条和子窗口的位置和大校

COleControl类为我们提供了这样的函数:

COleControl::OnSetObjectRects(LPCRECT lpRectPos, LPCRECT lpRectClip);

其中的参数给出了控件的新位置。重载此函数,先按系统提供的功能自动调整工具条,调用:

::SendMessage(m_hwndToolbar, TB_AUTOSIZE, 0L, 0L)

然后,同创建时一样计算控件窗口的客户区(参数lpRectPos已给出),调用GetWindowRect获得工具条的窗口大校为使子窗口填满控件中工具条以外的全部区域,应先计算出相应的矩形位置并调用m_TestEditSetWindowPos来 实现子窗口的位置调整。为了美观起见,也可在子窗口的四边留出少许富余。最后,调用基类的OnSetObjectRects函数。

3、实现对控件内对象的控制

因为有了子窗口,实际上用户的各项功能操作都是由子窗口来控制完成的。我们将焦点的控制权交给子窗口,使用户能进行输入和编辑操作,在CTestCtrl::OnSetFocus中调用m_TestEditSetFocus。同样,当控件对象捕获到工具条上的按钮被按下的消息时,要调用 m_TestEdit 的相应函数以执行用户的命令。

工具条上提示信息的显示也由控件对象来控制。在CTestCtrl::OnNotify函数中加入如下代码:

NMHDR pNMHDR = (NMHDR )lParam;

BOOL tmp;

if (pNMHDR->code == TTN_NEEDTEXT)

return OnToolbarNeedText(wParam, pNMHDR, tmp);

这样,当鼠标移动并停留在工具条的某个按钮上时,控件对象就会调用工具条模板类中的OnToolbarNeedText 函数以获得相应的提示信息。

4、控件窗口及内部对象的撤消

最后需要说明的是,如果我们在控件中创建了新的工具条和子窗口,则也应该及时撤消控件窗口及其内部对象。撤消控件窗口,即是在 CTestEdit::OnDestroy函数中依次调用DestroyToolbar和 m_TestEditDestroyWindow 来清除工具条和子窗口。

遵循以上四个工作步骤就可以很好地创建一个带有工具条和编辑子窗口的ActiveX控件。子窗口可由用户自己定义,象通常的应用程序那样去实现各种各样或简单或复杂的功能。工具条的存在使用户执行各项操作更加方便。此外,在控件中加进其它各种所需的对象并进行控制也是可能的。

RPC是远程过程调用(Remote Procedure Call)的缩写形式。

SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。

进程间通信(IPC)在多任务操作系统或联网的计算机之间运行的程序和进程所用的通信技术。有两种类型的进程间通信(IPC)。

本地过程调用(LPC)LPC用在多任务操作系统中,使得同时运行的任务能互相会话。这些任务共享内存空间使任务同步和互相发送信息。远程过程调用(RPC)RPC类似于LPC,只是在网上工作。RPC开始是出现在Sun微系统公司和HP公司的运行UNⅨ操作系统的计算机中。

原理

通过IPC和RPC,程序能利用其它程序或计算机处理的进程。客户机/服务器模式计算把远程过程调用与其它技术(如消息传递)一道,作为系统间通信的一种机制。客户机执行自己的任务,但靠服务器提供后端文件服务。RPC为客户机提供向后端服务器申请服务的通信机制。

如果你把客户机/服务器应用程序想作是一个分离的程序,服务器能运行数据访问部分,因为它离数据最近,客户机能运行数据表示和与用户交互的前端部分。这样,远程过程调用可看作是把分割的程序通过网络重组的部件。LPC有时也称耦合(Coupling)机制。

-RPC服务器

端游、手游服务端常用的架构是什么样的?

类型1:卡牌、跑酷等弱交互服务端卡牌跑酷类

因为交互弱,玩家和玩家之间不需要实时面对面PK,打一下对方的离线数据,计算下排行榜,买卖下道具即可,所以实现往往使用简单的 HTTP服务器:

登录时可以使用非对称加密(RSA, DH),服务器根据客户端uid,当前时间戳还有服务端私钥,计算哈希得到的加密 key 并发送给客户端。之后双方都用 HTTP通信,并用那个key进行RC4加密。客户端收到key和时间戳后保存在内存,用于之后通信,服务端不需要保存 key,因为每次都可以根据客户端传上来的 uid 和 时间戳 以及服务端自己的私钥计算得到。用模仿 TLS的行为,来保证多次 HTTP请求间的客户端身份,并通过时间戳保证同一人两次登录密钥不同。

每局开始时,访问一下,请求一下关卡数据,玩完了又提交一下,验算一下是否合法,获得什么奖励,数据库用单台 MySQL或者 MongoDB即可,后端的 Redis做缓存(可选)。如果要实现通知,那么让客户端定时15秒轮询一下服务器,如果有消息就取下来,如果没消息可以逐步放长轮询时间,比如30秒;如果有消息,就缩短轮询时间到10秒,5秒,即便两人聊天,延迟也能自适应。

此类服务器用来实现一款三国类策略或者卡牌及酷跑的游戏已经绰绰有余,这类游戏因为逻辑简单,玩家之间交互不强,使用 HTTP来开发的话,开发速度快,调试只需要一个浏览器就可以把逻辑调试清楚了。

类型2:第一代游戏服务器 1978

1978年,英国著名的财经学校University of Essex的学生 Roy Trubshaw编写了世界上第一个MUD程序《MUD1》,在University of Essex于1980年接入 ARPANET之后加入了不少外部的玩家,甚至包括国外的玩家。《MUD1》程序的源代码在 ARPANET共享之后出现了众多的改编版本,至此MUD才在全世界广泛流行起来。不断完善的 MUD1的基础上产生了开源的 MudOS(1991),成为众多网游的鼻祖:

MUDOS采用 C语言开发,因为玩家和玩家之间有比较强的交互(聊天,交易,PK),MUDOS使用单线程无阻塞套接字来服务所有玩家,所有玩家的请求都发到同一个线程去处理,主线程每隔1秒钟更新一次所有对象(网络收发,更新对象状态机,处理超时,刷新地图,刷新NPC)。

游戏世界采用房间的形式组织起来,每个房间有东南西北四个方向可以移动到下一个房间,由于欧美最早的网游都是地牢迷宫形式的,因此场景的基本单位被成为 “房间”。MUDOS使用一门称为LPC的脚本语言来描述整个世界(包括房间拓扑,配置,NPC,以及各种剧情)。游戏里面的高级玩家(巫师),可以不断的通过修改脚本来为游戏添加房间以及增加剧情。早年 MUD1上线时只有17个房间,Roy Trubshaw毕业以后交给他的师弟 Richard Battle,在 Richard Battle手上,不断的添加各种玩法到一百多个房间,终于让 MUD发扬光大。

用户使用 Telnet之类的客户端用 Tcp协议连接到 MUDOS上,使用纯文字进行游戏,每条指令用回车进行分割。比如 1995年国内第一款 MUD游戏《侠客行》,你敲入:”go east”,游戏就会提示你:“后花园 - 这里是归云庄的后花园,种满了花草,几个庄丁正在浇花。此地乃是含羞草生长之地。这里唯一的出口是 north。这里有:花待 阿牧(A mu),还有二位庄丁(Zhuang Ding)”,然后你继续用文字操作,查看阿牧的信息:“look a mu”,系统提示:“花待 阿牧(A mu)他是陆乘风的弟子,受命在此看管含羞草。他看起来三十多岁,生得眉清目秀,端正大方,一表人才。他的武艺看上去不是很高,出手似乎极轻”。然后你可以选择击败他获得含羞草,但是你吃了含羞草却又可能会中毒死亡。在早期网上资源贫乏的时候,这样的游戏有很强的代入感。

用户数据保存在文件中,每个用户登录时,从文本文件里把用户的数据全部加载进来,操作全部在内存里面进行,无需马上刷回磁盘。用户退出了,或者每隔5分钟检查到数据改动了,都会保存会磁盘。这样的系统在当时每台服务器承载个4000人同时游戏,不是特别大的问题。从1991年的 MUDOS发布后,全球各地都在为他改进,扩充,退出新版本,随着 Windows图形机能的增强。1997游戏《UO》在 MUDOS的基础上为角色增加的x,y坐标,为每个房间增加了地图,并且为每个角色增加了动画,形成了第一代的图形网络游戏。

因为游戏内容基本可以通过 LPC脚本进行定制,所以MUDOS也成为名副其实的第一款服务端引擎,引擎一次性开发出来,然后制作不同游戏内容。后续国内的《万王之王》等游戏,很多都是跟《UO》一样,直接在 MUDOS上进行二次开发,加入房间的地图还有角色的坐标等要素,该架构一直为国内的第一代 MMORPG提供了稳固的支持,直到 2003年,还有游戏基于 MUDOS开发。虽然后面图形化增加了很多东西,但是这些MMORPG后端的本质还是 MUDOS。随着游戏内容的越来越复杂,架构变得越来越吃不消了,各种负载问题慢慢浮上水面,于是有了我们的第二代游戏服务器。

类型3:第二代游戏服务器 2003

2000年后,网游已经脱离最初的文字MUD,进入全面图形化年代。最先承受不住的其实是很多小文件,用户上下线,频繁的读取写入用户数据,导致负载越来越大。随着在线人数的增加和游戏数据的增加,服务器变得不抗重负。同时早期 EXT磁盘分区比较脆弱,稍微停电,容易发生大面积数据丢失。因此第一步就是拆分文件存储到数据库去。

此时游戏服务端已经脱离陈旧的 MUDOS体系,各个公司在参考 MUDOS结构的情况下,开始自己用 C在重新开发自己的游戏服务端。并且脚本也抛弃了 LPC,采用扩展性更好的 Python或者 Lua来代替。由于主逻辑使用单线程模型,随着游戏内容的增加,传统单服务器的结构进一步成为瓶颈。于是有人开始拆分游戏世界,变为下面的模型:

游戏服务器压力拆分后得意缓解,但是两台游戏服务器同时访问数据库,大量重复访问,大量数据交换,使得数据库成为下一个瓶颈。于是形成了数据库前端代理(DB Proxy),游戏服务器不直接访问数据库而是访问代理,再有代理访问数据库,同时提供内存级别的cache。早年 MySQL4之前没有提供存储过程,这个前端代理一般和 MySQL跑在同一台上,它转化游戏服务器发过来的高级数据操作指令,拆分成具体的数据库操作,一定程度上代替了存储过程:

但是这样的结构并没有持续太长时间,因为玩家切换场景经常要切换连接,中间的状态容易错乱。而且游戏服务器多了以后,相互之间数据交互又会变得比较麻烦,于是人们拆分了网络功能,独立出一个网关服务 Gate(有的地方叫 Session,有的地方叫 LinkSvr之类的,名字不同而已):

把网络功能单独提取出来,让用户统一去连接一个网关服务器,再有网关服务器转发数据到后端游戏服务器。而游戏服务器之间数据交换也统一连接到网管进行交换。这样类型的服务器基本能稳定的为玩家提供游戏服务,一台网关服务1-2万人,后面的游戏服务器每台服务5k-1w,依游戏类型和复杂度不同而已,图中隐藏了很多不重要的服务器,如登录和管理。这是目前应用最广的一个模型,到今天任然很多新项目会才用这样的结构来搭建。

人都是有惯性的,按照先前的经验,似乎把 MUDOS拆分的越开性能越好。于是大家继续想,网关可以拆分呀,基础服务如聊天交易,可以拆分呀,还可以提供web接口,数据库可以拆分呀,于是有了下面的模型:

这样的模型好用么?确实有成功游戏使用类似这样的架构,并且发挥了它的性能优势,比如一些大型 MMORPG。但是有两个挑战:每增加一级服务器,状态机复杂度可能会翻倍,导致研发和找bug的成本上升;并且对开发组挑战比较大,一旦项目时间吃紧,开发人员经验不足,很容易弄挂。

比如我见过某上海一线游戏公司的一个 RPG上来就要上这样的架构,我看了下他们团队成员的经验,问了下他们的上线日期,劝他们用前面稍微简单一点的模型。人家自信得很,认为有成功项目是这么做的,他们也要这么做,自己很想实现一套。于是他们义无反顾的开始编码,项目做了一年多,然后,就没有然后了。

现今在游戏成功率不高的情况下,一开始上一套比较复杂的架构需要考虑投资回报率,比如你的游戏上线半年内 PCU会去到多少?如果一个 APRG游戏,每组服务器5千人都到不了的话,那么选择一套更为贴近实际情况的结构更为经济。即使后面你的项目真的超过5千人朝着1万人目标奔的话,相信那个时候你的项目已经挣大钱了 ,你数着钱加着班去逐步迭代,一次次拆分它,相信心里也是乐开花的。

上面这些类型基本都是从拆分 MUDOS开始,将 MUDOS中的各个部件从单机一步步拆成分布式。虽然今天任然很多新项目在用上面某一种类似的结构,或者自己又做了其他热点模块的拆分。因为他们本质上都是对 MUDOS的分解,故将他们归纳为第二代游戏服务器。

类型4:第三代游戏服务器

2007从魔兽世界开始无缝世界地图已经深入人心,比较以往游戏玩家走个几步还需要切换场景,每次切换就要等待 LOADING个几十秒是一件十分破坏游戏体验的事情。于是对于 2005年以后的大型 MMORPG来说,无缝地图已成为一个标准配置。比较以往按照地图来切割游戏而言,无缝世界并不存在一块地图上面的人有且只由一台服务器处理了:

每台 Node服务器用来管理一块地图区域,由 NodeMaster(NM)来为他们提供总体管理。更高层次的 World则提供大陆级别的管理服务。这里省略若干细节服务器,比如传统数据库前端,登录服务器,日志和监控等,统统用 ADMIN概括。在这样的结构下,玩家从一块区域走向另外一块区域需要简单处理一下:

玩家1完全由节点A控制,玩家3完全由节点B控制。而处在两个节点边缘的2号玩家,则同时由A和B提供服务。玩家2从A移动到B的过程中,会同时向A请求左边的情况,并向B请求右边的情况。但是此时玩家2还是属于A管理。直到玩家2彻底离开AB边界很远,才彻底交由B管理。按照这样的逻辑将世界地图分割为一块一块的区域,交由不同的 Node去管理。

对于一个 Node所负责的区域,地理上没必要连接在一起,比如大陆的四周边缘部分和高山部分的区块人比较少,可以统一交给一个Node去管理,而这些区块在地理上并没有联系在一起的必要性。一个 Node到底管理哪些区块,可以根据游戏实时运行的负载情况,定时维护的时候进行更改 NodeMaster 上面的配置。于是碰到第一个问题是很多 Node服务器需要和玩家进行通信,需要问管理服务器特定UID为多少的玩家到底在哪台 Gate上,以前按场景切割的服务器这个问题不大,问了一次以后就可以缓存起来了,但是现在服务器种类增加不少,玩家又会飘来飘去,按UID查找玩家比较麻烦;另外一方面 GATE需要动态根据坐标计算和哪些 Node通信,导致逻辑越来越厚,于是把:“用户对象”从负责连接管理的 GATE中切割出来势在必行于是有了下面的模型:

网关服务器再次退回到精简的网络转发功能,而用户逻辑则由按照 UID划分的 OBJ服务器来承担,GATE是按照网络接入时的负载来分布,而 OBJ则是按照资源的编号(UID)来分布,这样和一个用户通信直接根据 UID计算出 OBJ服务器编号发送数据即可。而新独立出来的 OBJ则提供了更多高层次的服务:

对象移动:管理具体玩家在不同的 Node所管辖的区域之间的移动,并同需要的 Node进行沟通。

数据广播:Node可以给每个用户设置若干 TAG,然后通知 Object Master 按照TAG广播。

对象消息:通用消息推送,给某个用户发送数据,直接告诉 OBJ,不需要直接和 GATE打交道。

好友聊天:角色之间聊天直接走 OBJ/OBJ MASTER。整个服务器主体分为三层以后,NODE专注场景,OBJ专注玩家对象,

GATE专注网络。这样的模型在无缝场景服务器中得到广泛的应用。但是随着时间的推移,负载问题也越来越明显,做个活动,远来不活跃的区域变得十分活跃,靠每周维护来调整还是比较笨重的,于是有了动态负载均衡。动态负载均衡有两种方法,第一种是按照负载,由 Node Master 定时动态移动修改一下各个 Node的边界,而不同的玩家对象按照先前的方法从一台 Node上迁移到另外一台 Node上:

图11 动态负载均衡

Node Master定时查找地图上的热点区域,计算新的场景切割方式,然后告诉其他服务器开始调整,具体处理方式还是和上面对象跨越边界移动的方法一样。但是上面这种方式实现相对复杂一些,于是人们设计出了更为简单直接的一种新方法:

图12 基于网格的动态负载均衡

于网格的动态负载均衡还是将地图按照标准尺寸均匀切割成静态的网格,每个格子由一个具体的Node负责,但是根据负载情况,能够实时的迁移到其他 Node上。在迁移分为三个阶段:准备,切换,完成。三个状态由Node Master负责维护。准备阶段新的 Node开始同步老 Node上面该网格的数据,完成后告诉NM;NM确认OK后同时通知新旧 Node完成切换。完成切换后,如果 Obj服务器还在和老的 Node进行通信,老的 Node将会对它进行纠正,得到纠正的 OBJ将修正自己的状态,和新的 Node进行通信。

很多无缝动态负载均衡的服务端宣称自己支持无限的人数,但不意味着 MMORPG游戏的人数上限真的可以无限扩充,因为这样的体系会受制于网络带宽和客户端性能。带宽决定了同一个区域最大广播上限,而客户端性能决定了同一个屏幕到底可以绘制多少个角色。

从无缝地图引入了分布式对象模型开始,已经完全脱离 MUDOS体系,成为一种新的服务端模型。又由于动态负载均衡的引入,让无缝服务器如虎添翼,容纳着超过上一代游戏服务器数倍的人数上限,并提供了更好的游戏体验,我们称其为第三代游戏服务端架构。网游以大型多人角色扮演为开端,RPG网游在相当长的时间里一度占据90%以上,使得基于 MMORPG的服务端架构得到了蓬勃的发展,然而随着玩家对RPG的疲惫,各种非MMORPG游戏如雨后春笋般的出现在人们眼前,受到市场的欢迎。

类型5:战网游戏服务器

经典战网服务端和 RPG游戏有两个区别:RPG是分区分服的,北京区的用户和广州区的用户老死不相往来。而战网,虽然每局游戏一般都是 8人以内,但全国只有一套服务器,所有的玩家都可以在一起游戏,而玩家和玩家之使用 P2P的方式连接在一起,组成一局游戏:

玩家通过 Match Making 服务器使用:创建、加入、自动匹配、邀请 等方式组成一局游戏。服务器会选择一个人做 Host,其他人 P2P连接到做主的玩家上来。STUN是帮助玩家之间建立 P2P的牵引服务器,而由于 P2P联通情况大概只有 75%,实在联不通的玩家会通过 Forward进行转发。

大量的连接对战,体育竞技游戏采用类似的结构。P2P有网状模型(所有玩家互相连接),和星状模型(所有玩家连接一个主玩家)。复杂的游戏状态在网状模型下难以形成一致,因此星状P2P模型经受住了历史的考验。除去游戏数据,支持语音的战网系统也会将所有人的语音数据发送到做主的那个玩家机器上,通过混音去重再编码的方式返回给所有用户。

战网类游戏,以竞技、体育、动作等类型的游戏为主,较慢节奏的 RPG(包括ARPG)有本质上的区别,而激烈的游戏过程必然带来到较 RPG复杂的多的同步策略,这样的同步机制往往带来的是很多游戏结果由客户端直接计算得出,那在到处都是破解的今天,如何保证游戏结果的公正呢?

主要方法就是投票法,所有客户端都会独立计算,然后传递给服务器。如果结果相同就更新记录,如果结果不一致,会采取类似投票的方式确定最终结果。同时记录本剧游戏的所有输入,在可能的情况下,找另外闲散的游戏客户端验算整局游戏是否为该结果。并且记录经常有作弊嫌疑的用户,供运营人员封号时参考。

类型7:休闲游戏服务器

休闲游戏同战网服务器类似,都是全区架构,不同的是有房间服务器,还有具体的游戏服务器,游戏主体不再以玩家 P2P进行,而是连接到专门的游戏服务器处理:

和战网一样的全区架构,用户数据不能象分区的 RPG那样一次性load到内存,然后在内存里面直接修改。全区架构下,为了应对一个用户同时玩几个游戏,用户数据需要区分基本数据和不同的游戏数据,而游戏数据又需要区分积分数据、和文档数据。胜平负之类的积分可以直接提交增量修改,而更为普遍的文档类数据则需要提供读写令牌,写令牌只有一块,读令牌有很多块。同帐号同一个游戏同时在两台电脑上玩时,最先开始的那个游戏获得写令牌,可以操作任意的用户数据。而后开始的那个游戏除了可以提交胜平负积分的增量改变外,对用户数据采用只读的方式,保证游戏能运行下去,但是会提示用户,游戏数据锁定。

类型8:现代动作类网游

从早期的韩国动作游戏开始,传统的战网动作类游戏和 RPG游戏开始尝试融合。单纯的动作游戏玩家容易疲倦,留存也没有 RPG那么高;而单纯 RPG战斗却又慢节奏的乏味,无法满足很多玩家激烈对抗的期望,于是二者开始融合成为新一代的:动作 + 城镇 模式。玩家在城镇中聚集,然后以开副本的方式几个人出去以动作游戏的玩法来完成各种 RPG任务。本质就是一套 RPG服务端+副本服务端。由于每次副本时人物可以控制在8人以内,因此可以获得更为实时的游戏体验,让玩家玩的更加爽快。

说了那么多的游戏服务器类型,其实也差不多了,剩下的类型大家拼凑一下其实也就是这个样子而已。

mknod /dev/leds_device c 210 0 //创建设备结点,主设备号是210,次设备号是0

insmod /home/ims_app/lpc32xx_led_moduleko//挂载驱动

udpsvd -vE 0 69 tftpd -c /home/app &//busybox内置的tftpd服务器的配置

// 上面的0表示对所有ip地址都进行侦听

// 如果设置为127001那么只能开发板本地arm可以进行ftp

// 比如开发板eth0的的ip地址设为1921681102,那么就不能通过该ip登录

// 所以上面指定ip等于0,那么无论来自127001还是1921681102网络地址的

// 数据都能使用tftpd服务器

// 参数-c表示允许client客户端上传文件到/home/tftpd

telnetd//启动服务器

楼主可以去找些busybox tftp 服务器配置的相关资料去看一下,希望对你有帮助。

Disk

access arm 磁头臂,存取臂

access time 存取时间

adder 加法器

address 地址

alphanumeric 字母数字的

analog computer 模拟计算机

analyst 分析员

area 区域

array 数组,阵列

assembler 汇编程序

automation 自动化

band 区

batch processing 成批处理

binary code 二进制码

binary digit 二进制位,二进制数字

bit 比特,二进制的一位

branch 分支,支线

brush 电刷

buffer storage 缓冲存储器

calculator 计算器

call instruction 呼叫指令

card punch 卡片穿孔机

card reader 卡片阅读机,读卡机

cell 单元

channel 通道,信道

character 字符

check digit 校验数位

circuit 电路,线路

to clear 清除,清零

clock 时钟

code 代码

to code 编码

coder 编码员,编码器

command 指令,命令

compiler 编译程序

computer language 计算机语言

console 控制台

control unit 控制部件,控制器

core storage, core store 磁心存储器

counter 计数器

cybernetics 控制论

cycle 循环

data 数据

data processing 数据处理

debugging 调试

decision 制定

digit 数字,数位,位

digital computer 数字计算机

disc, disk 磁盘

display unit 显示装置

drum 磁鼓

to edit 编辑

electronics 电子学

emitter 发射器

to encode 编码

to erase 擦除,清洗,抹除

feed 馈送,供给

to feed 馈送,供给

feedback 反馈

field 字段,信息组,域

file 文件

floppy disk 软磁盘

floppy disk drive 软磁盘机

flow chart 流程图

frame 帧

hardware 硬件

identifier 标识符

index 索引

information 信息

inline processing 内处理

input 输入

inquiry 询问

instruction 指令

integrated circuit 集成电路

to interpret 解释

item 项目,项

jump 转移

key 键,关键码

keyboard 键盘

latency time 等待时间

希望能对楼主有用。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 怎么样使用VC++设计ActiveX控件

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情