【问题标题】:Python pygame Client/Server runs slowPython pygame 客户端/服务器运行缓慢
【发布时间】:2020-04-27 12:50:53
【问题描述】:

我在 Youtube 上找到了一个基本的太空入侵者 pygame,我想对其进行修改,以便到目前为止,服务器正在执行所有处理和绘图,客户端只发送键盘输入(全部在 localhost 上运行) .问题是在我实现了这个机制之后,游戏不再那么灵敏了。当我按下一个键到船实际移动时,它似乎延迟了大约 1 秒(当从 pycharm 启动游戏时,当它从 cmd 启动时更糟)。

我不知道为什么会发生这种情况,因为实际上没有什么繁重的事情需要处理,我真的可以使用你的帮助。

我还监控了wireshark中的以太网流量,似乎每秒发送大约60-70个数据包。

这里是所有必需的东西的 github 链接:https://github.com/PaaulFarcas/C-S-Game

【问题讨论】:

  • 我无法复制问题,因为提供的代码对我不起作用。但我想这与套接字和阻塞有关。
  • 如果您从 Internet 来回发送请求,您会不会期望出现这种延迟?
  • 我预计会有一些延迟,但我没想到它会这么糟糕,即使服务器在数百英里外的机器上运行。使用这个非常基本的代码在我的本地机器上延迟 1-3 秒是不可接受的。我认为问题出在其他地方。

标签: python pygame client-server


【解决方案1】:

我希望主循环中的这段代码是问题所在:

    recv = conn.recv(661)
    keys = pickle.loads(recv)

套接字函数conn.recv()阻塞,直到收到 661 个字节,或者有一些套接字事件(如被关闭)。因此,您的程序正在阻塞等待数据到达的主循环的每次迭代。

您可以尝试按照manual 使用socket.setblocking( False )

但是我更喜欢使用select 模块 (manual link),因为我喜欢它提供的更好的控制水平。基本上,您可以使用它来了解 any 数据是否已到达套接字(或者是否有错误)。这为您提供了一个简单的 select-read-buffer 类型的逻辑循环:

procedure receiveSocketData
    Use select on the socket, with an immediate timeout.
    Did select indicate any data arrived on my socket?
        Read the data, appending it to a Rx-buffer
        Does the Rx-buffer contain enough for a whole packet?
            take the packet-chunk from the head of the Rx-buffer
            decode & return it
        Else
            Keep the Rx-Buffer somewhere safe
            return None
    Did any errors happen on my socket
        clear Rx-Buffer
        close socket
        return error

我猜想使用一个未知大小的数据包,你可以尝试 un-pickle 它,并在成功时返回 OK ......虽然这非常低效。我会使用固定大小的数据包和struct 模块按网络字节顺序打包和解包。

【讨论】:

  • 很好的解释。我也有类似的问题,会尝试你的解决方案。所以如果我理解正确,在main_loop 内部调用receiveSocketData 会模拟某种并发行为?
  • @kaktus_car - 不,重点是探测网络堆栈,并且仅在数据可用时尝试接收数据,而不是停止并等待。跨度>
猜你喜欢
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
  • 1970-01-01
相关资源
最近更新 更多