APP下载

基于多进程的抗击生物病毒游戏的设计与实现

2021-07-19曾雨阳赵建喆

电脑知识与技术 2021年14期
关键词:多线程

曾雨阳 赵建喆

摘要:隨着网络的迅速发展,多人在线游戏备受欢迎。选取抗击生物病毒的主题,通过多线程等技术开发了游戏,多个客户端可以通过socket连接服务器,实现通信与交互。旨在借助多人在线游戏的特点,传递抗击生物病毒的精神力量。

关键词:多进程;多线程;多人在线游戏

中图分类号:TP311      文献标识码:A

文章编号:1009-3044(2021)14-0047-02

Abstract: With the rapid development of the Internet, multiplayer online games are very popular. Fighting biological virus is selected as the topic of the game. Through multi-threading technology, the game is developed. To achieve communication and interaction, multiple clients can be connected to the server via socket. The spirit of fighting biological virus is transferred using the characteristics of multiplayer online games.

Key words: multi-process; multi-threading; multiplayer online game

1 背景

本文设计并实现了一个基于多进程、多人在线操作的抗击生物病毒游戏。

玩家可以自由控制自己的“医生”角色,当与对面来的病毒相遇时,玩家医生血量减少;当与对面来的疫苗或口罩道具相遇时,玩家会获得积分。

游戏实现了以下功能:上下左右按键自由控制“医生”角色的移动。随机生成病毒、疫苗和口罩道具,这些障碍物会以不同的速度匀速自上而下移动。玩家血量减少、玩家积分、失败和重新开始等。界面显示生命值和得分。

游戏具有多人联机协同的功能。客户端使用Java与Swing实现,服务端使用C/C++混合编程,实现了多进程、多线程、进程间通信和多路复用等技术[1-2]。

2 系统设计

2.1 架构设计

游戏客户端使用Java Swing作为前端GUI,使用Java作为客户端逻辑,服务端使用C/C++混合编程实现,客户端与服务端使用Socket TCP协议连接[3]。架构设计如图1所示。

客户端不负责进行关键逻辑判断,只负责接收消息并将处理后的消息展示到GUI界面,服务端负责实现病毒、口罩和疫苗道具等障碍物对象的生成、相遇判断等,有效地避免了客户端可能发生的作弊现象,保证了游戏的公平性与安全性。

服务端使用多进程、多线程、进程间通信和多路复用技术,实现思路如图2所示。

子进程用于运行游戏,异常退出等对于主进程的影响小。父子进程之间使用信号机制进行通信,子进程使用多线程同时处理数据,使用多路复用轮询所有客户端[4]。

2.2 server服务器端的逻辑

2.2.1 main()主运行进程

初始化内存,给服务器网络地址结构体sockaddr_in设置TCP协议,设置为可以连接任意的IP地址,服务器端口号设置为8888。按照socket()、bind()、listen()和accept()的顺序监听端口。

socket()获取服务器端socket的文件描述符,采用IPv4和TCP协议。bind()将服务器端socket绑定到服务器的地址和端口上(服务器网络地址结构体sockaddr_in)。listen()监听8888端口号上的连接请求,进入的连接请求在使用系统调用accept()应答之前要在进入队列中等待。signal(SIGUSR1, father_listen)设置信号的处理函数。

2.2.2 调用father_listen()函数

父进程监控为father_listen()。accept()处理连接8888端口的请求,获取客户端的socket文件描述符(用来调用send()和recv()),并放入玩家列表player_list中。对该客户端连接,fork()创建子进程,子进程中启动主客户端进程main_client。挂起父进程,直到收到SIGUSR1的信号。

2.2.3 main_client()主客户端进程

创建两个线程,分别用于调整障碍物移动obstacle_run和获取新客户端get_new_client。初始化障碍物列表,包括其种类和初始位置。服务器主进程通过多路复用以监听客户端。多路分离函数select()实现多路复用,在同一个线程内同时处理多个请求,不断轮询所负责的socket。监视fd文件描述符是否可读取,是否有数据到来。当可读取时,用recv()函数从TCP连接的另一端接收数据,存放在长度为1024的buff缓冲区中。以逗号为分界,切割客户端发来的数据字符串,处理数据。根据这些数据,在服务器中更新对应ID的玩家数据。连接成功后为客户端创建玩家控制对象,初始坐标随机。并用sendData()将数据发回客户端,通知连接成功。

3 关键部分程序实现

3.1 Socket通信

本游戏采用了Java Swing作为客户端,利用Socket在两种语言间发送消息[5]。在连接client和server的过程中,Java与C发送接收数据时应该将String类型的字符串中包含的字符转换成byte类型,存入到一个byte[]数组中,且应该指定编码形式,否则会出现乱码的现象(Java默认使用UTF-8,C++默认使用GBK),例如,使用语句toServer.write((ID + ",connected,").getBytes("GB2312"))。

在服务端,获取客户端的socket文件描述符作为客户端新的连接,其中包含客户端ip和port,具体语句如下:

client_socket = accept(server_socket, (struct sockaddr *)&remote_addr, (socklen_t *)&client_len);

服务端将这个请求的新文件描述符放到player_list中,视为一个新的玩家对象。如果客户端没有新的连接,则关闭客户端socket,并在父进程中,把调用进程挂起pause(),直至捕获到一个SIGUSR1的信号。

在客户端,通过while(true)循环读取服务器传来的数据,通过String(readBuff).trim()去除数据中的空白符,处理并判断服务器返回的数据,如果判断游戏结束,则显示“再来一次”按钮,并结束游戏,否则继续显示游戏操作提示信息和玩家当前坐标。

3.2 多线程

通过pthread_create()创建服务器全局障碍物调整的线程,如果创建成功,该函数返回值为零。同样方法创建第二个用于监听是否有新的客户端传入的线程。多线程以实现病毒、疫苗和口罩道具的匀速自上而下移动,以及多人在线操作的功能。

3.3 多路复用

使用select()函数实现多路复用,以监视fd文件描述符是否可以读取。select()函数会不断轮询所负责的socket,监测是否有数据到来。用recv()函数从TCP连接的另一端接收数据,存放在长度为1024的buf缓冲区中。具体实现方法如下:

ret_val = select( nfds: player_list[client_num - 1] +1, &rfds, writefds: NULL, exceptfds: NULL, stv);

recv(player_list[i], buf, n:1024, flags: 0)。

3.4 病毒、口罩和疫苗道具等障礙物的位置移动

使用obstacle_run()函数实现障碍物的移动。通过随机数发生器的初始化函数srand(),使用系统时间作为种子,以随机产生障碍物的种类。不同种类障碍物设置不同的移动步长,产生不同的移动速度效果。

遍历所有的障碍物对象,将障碍物所有服务端处理后的数据(如ID、位置、种类等)发送给玩家列表里所有的玩家客户端,以实现所有病毒、口罩和疫苗道具等障碍物的位置移动。

3.5 相遇检测

假设两个移动对象中心点的距离为变量a,两个移动对象的边缘矩形中心点对角线的距离为变量b,只要a小于b,那么就判定两者相遇。

4 总结

利用Java Swing构建界面,利用Java和C两种语言分别搭建客户端与服务端并进行交互,趣味性强。游戏为实时网络游戏,多个玩家连接服务器进行游戏,合理有效地使用了多进程、多线程、信号机制和多路复用等技术,数据交互具有较好的实时性和准确性。游戏的业务部分都在服务器端处理,而客户端主要用于接收用户的输入及显示,保证了游戏的公平性和安全性。

服务端具有一定的健壮性,具有较好的性能,游戏逻辑较为复杂(随机生成障碍物移动对象、键盘控制玩家对象、障碍物相遇检测等)。选择抗疫题材,玩家通过此游戏可以获得积极向上,共克时艰的昂扬精神力量,这样的游戏可以为抗击疫情贡献一份精神力量。

参考文献:

[1] 吕佳欢,蒋富,金易.基于Java的炸弹人游戏设计[J].电脑知识与技术,2020,16(25):97-98.

[2] Fang W J,Wang C L,Lau F C M.On the design of global object space for efficient multi-threading Java computing on clusters[J].Parallel Computing,2003,29(11/12):1563-1587.

[3] 傅玥,蔡兴富.Socket网络编程-基于TCP协议或UDP协议[J].中国新通信,2020,22(8):57-58.

[4] Himang M M,Himang C M,Ceniza A M,et al.Using an extended technology acceptance model for online strategic video games[J].International Journal of Technology and Human Interaction,2021,17(1):32-58.

[5] 刘贤梅,刘俊,贾迪.Unity引擎下多人在线网络游戏的设计与开发[J].计算机系统应用,2020,29(5):103-109.

【通联编辑:谢媛媛】

猜你喜欢

多线程
Java多线程同步机制在网络售票系统中的应用
Java并发工具包对并发编程的优化