访问【WRITE-BUG数字空间】_[内附完整源码和文档]
我们选择Tcp协议进行传输,之所以采用tcp,首先是因为tcp传输稳定,相比于udp不稳定的传输,tcp能确保消息一定传输出去。然后是tcp有服务器,相比于 p2p 无服务器模型,tcp 可以记录数据,方便用于商用而且也比较安全。
主要设计思路:
我们选择Tcp协议进行传输,之所以采用tcp,首先是因为tcp传输稳定,相比于udp不稳定的传输,tcp能确保消息一定传输出去。然后是tcp有服务器,相比于 p2p 无服务器模型,tcp 可以记录数据,方便用于商用而且也比较安全。
客户端主要设计思路:
基于TCP协议,实现发送消息给服务器和从服务器接收消息。要实现“迷你魔兽世界” 客户端的基本框架主要分为以下几个部分:
指令,根据输入的指令,比如login,move,attack等,客户端要判断指令的有效 指令设计,输入指令login playername,客户端向服务器发送登录请求,输入指令move direction,客户端向服务器发送移动请求,输入指令attcak playername,客户端发送攻击另一位玩家的请求,输入指令speak message,表示该玩家要发言,内容为message,同样要向服务器发送请求,输入指令logout,表示退出登陆。
无效指令,如果输入的不是约定好的指令以及指令结构不正确,则客户端不向服务器发送请求。第一,登陆时玩家名不能有空格;第二,move指令后面的方向必须在north,south, west和east这几个方向中,如果为其他内容,则输出无效的方向的提示;第三,输入attack 指令后要判断被攻击玩家是否在该玩家视野范围内,如果不在视野范围内,则输出错误信息 “The target is not visible”,玩家视野范围为(x-5,x+5),(y-5,y+5),x和y为玩家坐标;第四,speak生成的数据中可以有空格;第五,logout指令,没有参数。
发送请求,根据输入的有效指令得到消息类型和消息内容,按照协议打包成字节发送给服务器。
处理应答,客户端接收到来自服务器的包,根据协议,先解析出消息类型,再根据不同消息类型的包的结构解析出包中的数据,再根据这些数据输出消息。
线程问题,客户端必须和服务器端进行异步通信。例如,当其他玩家生成一个 speak 命令,客户端将会收到SPEAK_NOTIFY 信息从服务器端,尽管客户端没有请求这个消息。这意味着客户端不能阻塞用户的输入。所以将输入指令发送请求和接收广播/应答的函数设为两个线程,其中一个通过一个死循环,输入指令并处理,另一个也是通过死循环不停接收广播/应答并处理。
异常处理,当遇到一些特殊情况时需要做异常处理。
如果服务器端不可用并且连接不能生成,客服端必须退出,且显示错误信息”The gate to the tiny world of warcraft is not ready.”。要实现这一点,需要通过try/except 连接地址和端口号的时候检测异常。
如果客户端从服务器端收到一个异常消息,客户端必须退出,然后输出错误消息”Meteor is striking the world.”。即如果客户端收到的包的长度不符合规范,或者解析到的消息类型不存在或与包的长度不匹配,说明客户端收到了一个异常消息。
如果客户端和服务器端的连接被异常中断,客服端必须退出,然后显示一个错误消息”The gate to the tiny world of warcraft has disappeared.”。由于python中的套接字断开连接时不会出现异常,而是会不断接收到空字符,所以在接收消息的地方做一个判断,如果接收到的消息长度为0,说明连接断开,则执行该异常处理。