此游戏服务器操作系统使用UNIX,因为UNIX是标准的服务器操作系统,因此可以确保游戏的稳定性. 因此,以下所有程序均适用于UNIX.
服务器的总体架构如下: 通信模块,消息传递模块,游戏规则模块,线程管理模块,游戏世界管理模块.
通讯模块:
通信模块主要实现与客户端的通信功能. 实际上,通信模块是插座的封装. 套接字是UNIX下网络通信的基础. 我们可以读写套接字. 读取的数据来自客户端,写入的数据可以由客户端读取.
套接字主要有阻塞套接字和非阻塞套接字两种. 对于非阻塞套接字,每次读取和写入之后,无论读取和写入的字节数是否满足要求,它都会立即返回;否则,它将立即返回. 并用于阻塞如果读取和写入的字节数不够,则该函数将被阻塞,直到返回之前所有要处理的数据都已处理完. 可以看出,如果使用非阻塞套接字,网络传输将变得非常不稳定,并且当网络环境不好时,很难控制传输. 因此,对于我们的系统,将使用阻止模式.
我们面临的下一个问题是如何知道何时读入. 如果在不合适的时间从阻塞套接字读取数据,则线程很可能被阻塞. 在这里,选择使用的是复用技术,其原理是监视我们的套接字. 如果套接字上发生读取事件,则将调用消息模块以将消息发送到套接字的携带对象以对其进行读写.
以下是Socket的简单封装:
SSocket类
{
fd_set * SockSet; // fd_set,这是我们选择的集
char IsListenSocket; //是否是套接字
int ServerPort; //套接字的端口号
struct sockaddr_in addr; //地址信息
公开
:
SSocket();
〜SSocket();
int Socket; //套接字
int CreateListenSocket(fd_set * sset,int Port,char * addr); //初始//转换套接字
int AcceptSocket(int listen_fd,fd_set * sset); //初始化一个非套接字
int CloseSocket(); //关闭插座
int SendBuf(void * buf,int size); //发送数据
int RecvBuf(void * buf,int size); //接收数据
int SetSocketFd(); //将套接字添加到侦听集
int ClrSocketFd(); //从侦听集合中清除套接字
};
通过封装套接字,我们完成了通信模块的基本任务. 下一步是在网络上传输消息. 这时,有必要继续封装SSocket. 首先,定义消息结构,然后读取和写入消息. 消息的结构根据每个游戏的不同而有所不同,因此在此我将不对其进行深入讨论.
线程管理模块:
因为我们使用阻止模式,所以这意味着我们必须为每个套接字创建单独的线程,否则可能导致服务器停止工作. 因此,我们需要封装线程. 包的内容主要包括: 线程函数地址,线程启动时间,线程最后阻塞时间,线程最大阻塞时间,线程启动方法,线程停止方法. 线程停止方法可以通过向线程发送信号来杀死线程.
线程类封装完成后,我们可以开始编写管理模块代码. 管理模块实际上是一个线程. 它的第一个功能是监视每个线程是否因超时而被阻塞. 通过查看线程的最后阻塞时间和最大阻塞时间来完成此操作. 一旦发现当前时间超过线程的最大阻塞时间加上线程的最后阻塞时间,就可以确定线程阻塞超时,并且此时需要杀死线程. 此外,此模块还负责其他一些与根线程相关的管理方法.
消息传递模块:
如何在对象和模块之间传递消息也是服务器端设计的重点. 简化示例解释如下: 如果一个播放器向另一个播放器发送消息,则首先通过通信模块接收数据,然后使用消息收发模块通知另一个播放器,然后另一个播放器的线程调用该通信. 发送消息的模块发送回客户端,这是消息传递模块的作用.
如何封装消息模块?第一步是制作一个MessageBox类,该类主要是通过pop和push方法加载消息的堆栈. 当然,我们不能忘记必须实现存储消息数据结构. 封装的第二步是HandleMessage类,它是我们消息模块的主要实现. 有一个WaitMessage方法,调用此方法后,线程将被阻塞,直到消息到达为止. 这可以通过在UNIX下使用sem的未命名信号量来实现,该信号量可以增加或减少信号量以实现互斥. 但是,肯定会有人问,为什么我们有WaitMesssage网络游戏服务器端编程 pdf,这不会导致线程阻塞?实际上,服务器端是被动驱动模型,就像汽车不踩就不会行驶一样. 如果没有新闻要驱动,则服务器端将无法运行.
实现上述封装后,在两个对象之间发送消息变得非常简单. 我们可以直接使用SendMessage方法. SendMessage的实现也非常简单. 调用MessageBox中的Push方法将消息放入,然后将sem加1,以便在接受此消息时可以接收到消息.
其他:
其余两个模块与游戏有关. 实际上网络游戏服务器端编程 pdf,它们是两个更复杂的模块. 这两个模块的实现根据要编写的游戏而有所不同. 但是,它们究竟是做什么的?这是一个示例说明:
假设我们当前正在开发RPG游戏,我们的玩家将使游戏角色在屏幕上向前迈进. 这时,他们向服务器发送移动请求. 服务器的通信模块收到该消息后,会通知游戏世界管理模块,游戏世界管理模块将调用游戏规则模块,以确定玩家的请求是否符合规则(是否合法). 如果可以移动,游戏管理模块将更改其坐标,并最终通知其相关玩家. 换句话说,规则模块实际上专用于游戏业务逻辑,而管理模块实际上专用于游戏对象.
摘要
开始开发游戏非常困难. 实际上,本文只能作为起点,并且仅告诉您入门的方法. 剩下的,以及烦人的逐行实现代码.
我真的很想和对游戏设计感兴趣的人交流
sunxing@cosco-logistics-km.com.cn
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-203396-1.html
阿利伯克级驱逐舰是老旧军舰
导致北洋舰队大东沟海战失利
正义的国家站在正义的立场应该坚决予以反击