You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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))

验证步骤

  1. 确保game.py存在,且包含Game类及resetWent()、play()、connected()、bothWent()、get_player_move()、winner()等必要方法
  2. 启动服务器脚本,确认控制台输出绑定IP
  3. 修改network脚本中的服务器地址为上述IP
  4. 启动两个客户端窗口(需两名玩家才能进入游戏流程)
  5. 测试猜拳功能,检查控制台是否仍出现"Couldn't get game"提示

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:06:28