Python多人在线猜拳游戏:客户端与服务器无法通信求助
多人在线猜拳游戏通信故障排查与修复
我参考YouTube视频开发了一款Python多人在线猜拳游戏,运行时客户端控制台提示"Couldn't get game",这是客户端未收到服务器游戏数据时的触发提示,目前服务器与客户端无法正常交换信息。程序依赖network脚本(客户端收发消息)和game脚本(服务器运行游戏),尚未完成开发。
核心问题定位与修复
1. 服务器地址配置不匹配
network脚本中硬编码的服务器地址"240.2.2.1"为无效地址,而服务器端通过socket.gethostbyname(socket.gethostname())获取本地IP,两者不匹配导致客户端无法建立连接。
修复方案:
- 服务器启动后,查看控制台输出的绑定IP,或通过
ipconfig/ifconfig命令获取本地IPv4地址 - 将network脚本中的
self.server修改为服务器实际IP,本地测试可直接用"127.0.0.1",局域网测试用服务器的局域网IP
2. 服务器线程逻辑错误
threaded_client函数中,处理完单次请求后就执行了游戏清理、连接关闭操作,导致连接直接断开,无法维持长连接通信。这些清理代码应放在循环外部,仅在连接断开或游戏失效时执行。
修复后的threaded_client函数:
def threaded_client(conn, p, gameId): global idCount conn.send(str.encode(str(p))) reply = "" while True: try: data = conn.recv(4096).decode() if gameId in games: game = games[gameId] if not data: break else: if data == "reset": game.resetWent() elif data != "get": game.play(p, data) reply = game conn.sendall(pickle.dumps(reply)) else: break except: break # 连接断开后再执行清理操作 try: del games[gameId] print("Closing game", gameId) except: pass idCount -= 1 conn.close()
3. 客户端按钮显示异常
客户端按钮的y坐标设为500,与窗口高度一致,导致按钮完全显示在窗口外,无法点击操作。
修复方案:
调整按钮的y坐标,将其移入窗口可见区域:
btns = [Button("Rock", 50, 350, (0,0,0)), Button("Scissors", 250, 350, (255,0,0)), Button("Paper", 450, 350, (0,255,0))]
4. Network类异常处理不严谨
send方法捕获异常后仅执行str(e),未抛出异常或返回错误标识,导致客户端无法准确感知通信故障,只能通过外层try-except捕获泛型错误。
优化方案:
def send(self, data): try: self.client.send(str.encode(data)) return pickle.loads(self.client.recv(2048)) except socket.error as e: print(f"通信错误: {e}") raise # 重新抛出异常,让上层逻辑处理
5. 客户端平局判断逻辑错误
客户端判断平局时直接调用game.winner属性,但正确逻辑应为调用game.winner()方法,与胜利条件判断保持一致。
修复方案:
elif game.winner() == -1: text = font.render("Tie Game!", 1, (255, 0, 0))
验证步骤
- 确保
game.py存在,且包含Game类及resetWent()、play()、connected()、bothWent()、get_player_move()、winner()等必要方法 - 启动服务器脚本,确认控制台输出绑定IP
- 修改network脚本中的服务器地址为上述IP
- 启动两个客户端窗口(需两名玩家才能进入游戏流程)
- 测试猜拳功能,检查控制台是否仍出现"Couldn't get game"提示
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

