Получение нескольких сообщений через сокетсервер, но одно из них отправлено

1

A имеют приложение с двумя потоками. Его сетевая управляемая игра,

1. thread (Server)

  • Принимать соединения сокетов и получать сообщения
  • Когда сообщение отправляется, создайте событие и добавьте его в очередь

Код:

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 мс

Так выглядит игра. Управляющие сообщения - это просто скорости для маленького квадрата.

Изображение 174551

Для отладки я подключаюсь к серверу с виртуальной машины с помощью:

ncat 192.168.56.1 2000

Затем отправьте контрольные сообщения. В производстве эти сообщения будут отправляться каждые 50 мс на Android-устройство.

Проблема

В моей среде отладки я вручную печатаю сообщения с периодом в несколько секунд. За время я ничего не набираю, игра получается многократно. Случается, что message (в коде сервера) постоянно отображается с ранее полученным значением.

Я посылаю следующее:

1:0.5

На консоли, на которой запущено приложение, я получаю следующее сообщение из print message в коде сервера:

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

То, что делает игра, это действие, поскольку оно постоянно (с периодом, который он отображает, и не каждые несколько секунд, когда я набираю), получая это значение.

SInce, что произойдет, я ожидаю, что print message которое находится в while True также выводит постоянно и что выход:

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

Однако это не так. Просьба сообщить (я также открыт для предложений, чтобы сменить тему, если она недостаточно объяснительна)

  • 0
    Сервер не должен получать несколько сообщений, когда отправлено только одно. Я мог бы догадаться, что поток 2 получает событие и удерживает его, пока не получит новое событие.
Теги:
pygame
sockets

1 ответ

3
Лучший ответ

Ваш while True loop производит опрос сокета, который будет получать сообщения только при их отправке; он не знает и не заботится о том, что делает пользователь потока вниз по течению с этими сообщениями, он просто отправит событие и распечатает содержимое следующей записи в очереди на сокеты каждые 0,6 секунды. Если вы хотите, чтобы игра печатала текущую команду в каждом цикле рендеринга, вам придется поместить оператор print в цикл рендеринга, а не в poller-сокет. Кроме того, поскольку вы, похоже, хотите, чтобы последняя команда "приклеивалась" и не отправляла новое событие, если пользователь не вводит что-либо, вам может понадобиться поместить if message: блокировать код отправки события в обработчике сокетов, который у вас есть здесь, Прямо сейчас, вы будете отправлять пустое событие каждые 0,6 секунды, если пользователь не предоставил вам никакого ввода с момента последнего проверки.

Я также не думаю, что, вероятно, рекомендуется sleep или цикл, который у вас есть, в вашем обработчике сокетов. SocketServer будет вызывать его каждый раз, когда вы получаете данные в сокете, так что цикл эффективно выполняется для вас, и все, что делает это здесь, - это открыть вас, чтобы переполнить буфер, я думаю. Если вы хотите контролировать, как часто вы отправляете события в pygame, вы, вероятно, захотите сделать это, либо заблокировав события определенного типа, либо добавив их, если они уже поставлены в очередь, либо, захватив все события заданного типа из очереди каждый а затем просто игнорирует все, кроме первого или последнего. Вы также можете контролировать это, проверив обработчик, если это было некоторое количество времени с момента последнего опубликованного события, но тогда вы должны убедиться, что потребитель событий способен обрабатывать очередь событий с несколькими событиями, ожидающими на нем, и делает соответствующую очистку очереди при необходимости.

Редактировать:

Документы:

Разница в том, что вызов readline() во втором обработчике будет вызывать recv() несколько раз, пока он не встретит символ новой строки, в то время как единственный вызов recv() в первом обработчике просто вернет то, что было отправлено клиентом в одном sendall().

Так что да, чтение всей строки гарантировано. На самом деле, я не думаю, что try необходима, так как это даже не будет вызвано, если не будет ввода для обработки.

  • 0
    +1 за упоминание о том, что сервер управляется событиями ( docs.python.org/2/library/… )
  • 0
    Я думаю, что ответ будет более понятным на примере. Я полагаю, что совет - отбросить операторы while и sleep, не так ли?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню