通过套接字服务器接收多条消息,但发送了一条 [英] Receiving multiple messages via socketserver but one is sent

查看:53
本文介绍了通过套接字服务器接收多条消息,但发送了一条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A have a application with two threads. Its a network controlled game,

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 毫秒根据消息渲染一次游戏

这就是游戏的样子.控制消息只是小方块的速度.

This is how the game looks. The control messages are just speeds for the little square.

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

For the purpose of debug i connect to the server from a virtual machine with:

ncat 192.168.56.1 2000

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

And then send control messages. In production, these messages will be sent every 50ms by an Android device.

问题

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

In my debug environment, i manually type messages with a period of a few seconds. During the time i don't type anything the game gets rendered many times. What happens is that the message (in server code) is constantly rendered with the previously received value.

我发送以下内容:

1:0.5

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

On the console where the app is started i receive the following due to line print message in Server code:

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

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

What the game does is it acts as it is constantly (with the period it renders, and not every few seconds as i type) receiving this value.

既然发生了,我希望 print messagewhile True 中也不断输出,并且输出是:

SInce that is happenig i would expect that the print message which is in while True also outputs constantly and that the output is:

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

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

However that is not the case. Please advise (I'm also open for proposals to what to change the subject to if it isn't explanatory enough)

推荐答案

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

Your while True loop is polling the socket, which is only going to get messages when they are sent; it has no idea or care what the downstream event consumer is doing with those messages, it is just going to dispatch an event for and print the contents of the next record on the socket queue every .6 seconds. If you want the game to print the current command every render loop, you'll have to put the print statement in the render loop itself, not in the socket poller. Also, since you seem to want to have the last command "stick" and not post a new event unless the user actually inputs something, you might want to put an if message: block around the event dispatch code in the socket handler you have here. Right now, you'll send an empty event every .6 seconds if the user hasn't provided you any input since the last time you checked.

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

I also don't think it's probably advisable to put a sleep, or the loop you have for that matter, in your socket handler. The SocketServer is going to be calling it every time you receive data on the socket, so that loop is effectively being done for you, and all doing it here is going to do is open you up to overflowing the buffer, I think. If you want to control how often you post events to pygame, you probably want to do that by either blocking events of a certain type from being added if there is already 1 queued, or by grabbing all events of a given type from the queue each game loop and then just ignoring all but the first or last one. You could also control it by checking in the handler if it has been some amount of time since the last event was posted, but then you have to make sure the event consumer is capable of handling an event queue with multiple events waiting on it, and does the appropriate queue flushing when needed.

文档:

区别在于第二个处理程序中的 readline() 调用会多次调用 recv() 直到遇到换行符,而第一个处理程序中的单个 recv() 调用只会返回从客户端在一次 sendall() 调用中.

The difference is that the readline() call in the second handler will call recv() multiple times until it encounters a newline character, while the single recv() call in the first handler will just return what has been sent from the client in one sendall() call.

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

So yes, reading the whole line is guaranteed. In fact, I don't think the try is necessary either, since this won't even be called unless there is input to handle.

这篇关于通过套接字服务器接收多条消息,但发送了一条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆