“直播”俄罗斯方块——linux服务器编程

“直播”俄罗斯方块

展示图片在项目文件夹里

项目概述:类似于当前火热的直播平台,该项目由一个服务端,两种客户端构成。直播的玩家选择直播客户端,输入房间号,在本机运行俄罗斯方块游戏。观看直播的人登录观战客户端,输入想看的直播房号,进入可以实时观看到“主播”的游戏实况。还具有聊天室功能。

代码地址:https://github.com/zzaiyuyu/tetris-net/

使用说明:

./server 8080
./client 127.0.0.1 8080
./viewer 127.0.0.1 8080

项目总共分为三个模块

  1. 玩家客户端
  2. 观战客户端
  3. 服务器客户端

核心流程

  1. 服务器在某个地址上监听
  2. 玩家客户端和服务器建立TCP连接,输入房间号创建直播间,开始游戏
  3. 观战客户端建立连接,输入房间号进入直播间,开始观战或聊天

玩家客户端

MVC的设计思想

model部分

每一个图形用一个5X5数组表示,有图案则置为1,无则0.这样总共可以把全部的7类图形用一个结构体数组描述出来。

同时游戏还需要当前正在下落的图案的坐标。


control部分

主流程:

主控制逻辑设置一个定时器,并且捕捉ALRM信号,每过一定时间就自动下落一格。

下落过程中需要判断下一个位置是不是可以走,如果可以走,就擦出当前图案,在下一个位置画出来,如果不能走,就是碰到物体了,需要检测是不是该消除,游戏结束,之后就要开始下一个块了。

其中在判断下一步是否可行时,需要当前整个图案信息才能判断是否碰到物体了,所以在每一次碰到物体首先要保存当前的整体背景。

如何控制方向?

在主控流程加一个死循环,不断的判断是否有按键产生。判断按键首先要设置终端模式,标准输入是键盘输入到内核缓存,输入回车后才进入程序地址空间,将其改为键盘输入直接进入应用程序。然后非阻塞的读取输入程序地址的输入缓存区。

终端属性
这里写图片描述

假如按了左键,首先判断下一个位置可行不可行,若是非法操作,则恢复上一个图案。假如按上键,利用旋转函数对当前图案进行旋转

旋转算法
这里写图片描述

如何设置不同颜色块,显示下一个形状?

在定时下落的函数里,如果碰到不能走的情况,说明要出下一个块了,此时设置一个随机数,造成不同颜色块的效果。同理只需要一个临时变量nextBuf即可记录下一个形状。


view部分

VT100 实现终端画布式打印

观战客户端

观战客户端也遵循经典流程,构造请求,序列化,发送请求,等待响应,解析响应。

建立连接后首先发送请求加入直播间的消息,若服务器端关闭连接则客户端也关闭,证明房间不存在。

之后用poll调用同时监听标准输入和建立好的TCP套接字,若有标准输入则序列化发送给服务器,若有连接读事件则反序列化显示为游戏画面。

这里采用的是自定义的定长协议,一个结构体里包含了消息类型字段以及数据。

服务器

这里写图片描述
服务器的经典流程,读取请求,反序列化消息,调用业务逻辑代码,序列化的响应结果,发送。

服务器提前为每一个用户开辟一块内存用来保存数据,socket刚好对应了数组下标。

服务器用epoll多路IO转接,对监听套接字送上来的连接创建套接字后同一做读事件监听。之后按客户端发的消息类型进行区分

1代表请求创建直播间,之后不断监听玩家套接字

2请求加入直播间,之后不断监听读事件向其发送图案信息

3我是图案信息,需要转发给房间内的所有人

4我是聊天信息,需要转发给房间内的所有人

首先利用位图查询房间是否存在,非法情况就关闭连接。

这时再维护一个指针数组,数组下标对应了房间号,通过房间号这个句柄建立房间的观战者队列,转发消息都是操纵这个队列来的。

FAQ

  1. 网络连接不好的时候怎么办?

如果是客户端网不好的情况,由于采用TCP协议,TCP报文的序号保证了有序性,延迟过后瞬间从TCP接收缓冲区拿走很多数据,结果就是屏幕上有快进的效果。
连接超时和超时重传问题都由TCP协议接管,我可以不做考虑。
服务器网不好的情况,开始使用的是阻塞套接字,在read读取数据有可能部分数据来了,触发了epoll_wait, 然后read返回的实际字节数小于想要读取的,这时没做处理的话下次下半截数据到来的时候就会有粘包问题
之后改为非阻塞,并且使用recv的peek方法解决。
并且在发送大量数据时有可能写失败,先尝试写一次,查看实际放入缓冲区字节够不够,write返回实际写入缓冲区的字节数,不够就设置关心发送缓冲区的写事件,并且在写事件里再判断。
(必须是非阻塞的socket)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值