Python 通过socketserver接收多条消息,但发送了一条

Python 通过socketserver接收多条消息,但发送了一条,python,sockets,pygame,Python,Sockets,Pygame,A有一个具有两个线程的应用程序。这是一个网络控制的游戏 一,。线程(服务器) 接受套接字连接并接收消息 发送消息时,创建一个事件并将其添加到队列中 代码: 二,。线程(pygame) 负责游戏渲染 通过服务器填充的事件队列接收消息 每60毫秒根据消息渲染一次游戏 这就是游戏的样子。控制信息只是小广场的速度 为了进行调试,我使用以下设备从虚拟机连接到服务器: ncat 192.168.56.1 2000 然后发送控制消息。在生产过程中,这些消息将由安卓设备每50毫秒发送一次 问题 在调

A有一个具有两个线程的应用程序。这是一个网络控制的游戏

一,。线程(服务器)

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

二,。线程(pygame)

  • 负责游戏渲染
  • 通过服务器填充的事件队列接收消息
  • 每60毫秒根据消息渲染一次游戏
这就是游戏的样子。控制信息只是小广场的速度

为了进行调试,我使用以下设备从虚拟机连接到服务器:

ncat 192.168.56.1 2000
然后发送控制消息。在生产过程中,这些消息将由安卓设备每50毫秒发送一次

问题

在调试环境中,我手动键入几秒钟的消息。在这段时间里,我没有输入任何东西,游戏被渲染了很多次。发生的情况是,
消息
(在服务器代码中)不断地以先前接收到的值呈现

我谨此致函如下:

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

alan@alan ~/.../py $ python main.py 
1:0.5
游戏所做的是它不断地(在它呈现的时间段内,而不是在我输入时每隔几秒钟)接收这个值

既然发生了这种情况,我希望
中的
打印消息
,而True
也会持续输出,并且输出为:

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

但事实并非如此。请提供建议(如果没有足够的解释,我也愿意接受关于如何更改主题的建议)

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

我也不认为在套接字处理程序中设置
睡眠
,或者为此而设置的循环是明智的。
SocketServer
将在您每次收到套接字上的数据时调用它,这样循环就可以有效地为您完成,我认为,在这里执行此操作将使您的缓冲区溢出。如果您想控制将事件发布到pygame的频率,您可能希望通过阻止添加特定类型的事件(如果已经有1个排队),或者从每个游戏循环的队列中获取给定类型的所有事件,然后忽略除第一个或最后一个外的所有事件。您还可以通过检查处理程序来控制它,如果自上一个事件发布以来已经有一段时间了,那么您必须确保事件使用者能够处理有多个事件等待的事件队列,并在需要时进行适当的队列刷新

编辑:

:

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


所以是的,阅读整行是有保证的。事实上,我也不认为
try
是必要的,因为除非有输入要处理,否则它甚至不会被调用;它不知道也不关心下游事件消费者对这些消息做了什么,它只是将为发送一个事件,并每隔0.6秒打印套接字队列上下一条记录的内容。如果希望游戏在每个渲染循环中打印当前命令,则必须将
print
语句放入渲染循环本身,而不是套接字轮询器中。此外,由于您似乎希望最后一个命令“stick”并且在用户实际输入某些内容之前不发布新事件,因此您可能希望在此处的套接字处理程序中的事件分派代码周围放置一个
if消息:
块。现在,如果用户自上次检查以来未向您提供任何输入,则每0.6秒发送一次空事件

我也不认为在套接字处理程序中设置
睡眠
,或者为此而设置的循环是明智的。
SocketServer
将在您每次收到套接字上的数据时调用它,这样循环就可以有效地为您完成,我认为,在这里执行此操作将使您的缓冲区溢出。如果您想控制将事件发布到pygame的频率,您可能希望通过阻止添加特定类型的事件(如果已经有1个排队),或者从每个游戏循环的队列中获取给定类型的所有事件,然后忽略除第一个或最后一个外的所有事件。您还可以通过检查处理程序来控制它,如果自上一个事件发布以来已经有一段时间了,那么您必须确保事件使用者能够处理有多个事件等待的事件队列,并在需要时进行适当的队列刷新

编辑:

:

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