1

一个有两个线程的应用程序。它是一个网络控制的游戏,

1.线程(服务器)

  • 接受套接字连接并接收消息
  • 发送消息时,创建一个事件并将其添加到队列中

代码:

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        try:
            while True:
                sleep(0.06)
                message = self.rfile.readline().strip()              
                my_event = pygame.event.Event(USEREVENT, {'control':message})
                print message
                pygame.event.post(my_event)

2.线程(pygame)

  • 负责游戏渲染
  • 通过服务器填充的事件队列接收消息
  • 每 60 毫秒根据消息渲染游戏

这就是游戏的外观。控制消息只是小方块的速度。

在此处输入图像描述

为了调试,我从虚拟机连接到服务器:

ncat 192.168.56.1 2000

然后发送控制消息。在生产中,这些消息将由 Android 设备每 50 毫秒发送一次。

问题

在我的调试环境中,我以几秒钟的时间手动键入消息。在此期间,我不输入任何内容,游戏被渲染了很多次。发生的事情是message(在服务器代码中)不断地用先前接收到的值呈现。

我发送以下内容:

1:0.5

在启动应用程序的控制台上,由于print message服务器代码中的行,我收到以下信息:

alan@alan ~/.../py $ python main.py 
1:0.5

游戏所做的是它不断地接收这个值(随着它呈现的时间段,而不是我输入的每隔几秒)接收这个值。

因为那是发生的,我希望print messagewhich is inwhile True也不断输出,并且输出是:

alan@alan ~/.../py $ python main.py 
1:0.5
1:0.5
1:0.5
1:0.5
....

然而事实并非如此。请告知(如果解释性不够,我也愿意建议将主题更改为什么)

4

1 回答 1

4

您的while True循环正在轮询套接字,它只会在发送消息时获取消息;它不知道也不关心下游事件消费者对这些消息做了什么,它只是每 0.6 秒为套接字队列分派一个事件并打印下一条记录的内容。如果您希望游戏在每个渲染循环中打印当前命令,则必须将print语句放在渲染循环本身中,而不是在套接字轮询器中。此外,由于您似乎希望最后一个命令“坚持”并且不发布新事件,除非用户实际输入某些内容,您可能想要放置一个if message:阻止您在此处拥有的套接字处理程序中的事件调度代码。现在,如果用户自您上次检查后未向您提供任何输入,您将每 0.6 秒发送一个空事件。

我也不认为sleep在您的套接字处理程序中放置一个 或您拥有的循环可能是不可取的。这SocketServer每次你在套接字上接收数据时都会调用它,所以这个循环实际上是为你完成的,我认为这里所做的一切都是让你打开缓冲区溢出。如果您想控制向 pygame 发布事件的频率,您可能希望通过阻止添加某种类型的事件(如果已经有 1 个排队)或通过从队列中获取给定类型的所有事件来做到这一点。游戏循环,然后忽略除第一个或最后一个之外的所有内容。您也可以通过检查处理程序来控制它,如果自最后一个事件发布以来已经有一段时间了,但是您必须确保事件使用者能够处理一个事件队列,其中有多个事件在等待它,并且在需要时进行适当的队列刷新。

编辑:

文档

不同之处在于第二个处理程序中的 readline() 调用将多次调用 recv() 直到遇到换行符,而第一个处理程序中的单个 recv() 调用将只返回从客户端发送的内容sendall() 调用。

所以是的,保证阅读整行。事实上,我也不认为这try是必要的,因为除非有输入要处理,否则它甚至不会被调用。

于 2013-01-14T17:16:03.547 回答