2012-10-13 3 views
2

Я впервые использую сокеты в Python, и у меня есть проблема.Передача аргументов обработчику UDP в Python

У меня есть обработчик обработанного потока для моего UDP-сервера, но из-за его работы (как предложено here) Я не могу понять, как передать ему аргументы. Мне нужно, чтобы он обращался к другим объектам приложения, потому что он должен уведомлять их о действиях, выполняемых разными клиентами в сети. Однако класс, представляющий обработчик, не может быть создан, поэтому он не может принимать аргументы через конструктор.

Это упрощенная версия моего кода.

class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):   

    def handle(self): 
     data = self.request[0].strip()   
     socket = self.request[1] 
     print ("{} wrote:".format(self.client_address[0])) 
     print (data) 
     #Ideally, I'd call a method of an object here 


class ThreadedUDPServer(socketserver.ThreadingMixIn, socketserver.UDPServer): 
    pass 


class ServerManager(): 

    def __init__(self, player_box): 
     self.player_box = player_box 
     HOST, PORT = "xxx.xxx.xxx.xxx", 9999 
     self.server = ThreadedUDPServer((HOST, PORT), ThreadedUDPRequestHandler) 
     ip, port = self.server.server_address 

    def start(self):    
     server_thread = threading.Thread(target=self.server.serve_forever) 
     server_thread.start() 

    def stop(self): 
     self.server.shutdown() 

В этом случае для доступа к объекту, к которому я хочу обращаться, является player_box. Цель состоит в том, чтобы вызвать метод этого объекта каждый раз, когда делается запрос. Есть ли способ сделать это, или я должен использовать другой подход?

Я заметил, что есть аналогичный вопрос here, но предлагаемое решение для меня не работает. На самом деле, это не имеет большого смысла для меня ...

+0

уже есть сокетсер.ThreadedUDPServer – jfs

+0

@ J.F. Себастьян. Эта структура была предложена в приведенной мной ссылке. Однако, я думаю, вы можете ссылаться на ThreadingUDPServer, хотя я игнорирую, если предполагается, что разница между ними. – broncoAbierto

+0

Да, это опечатка: 's/ed/ing /'. См. [Источник] (http://hg.python.org/cpython/file/default/Lib/socketserver.py#l627) – jfs

ответ

1

Это может быть немного некрасиво, но это лучшая идея, у меня есть:

class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler): 
    PLAYER_BOX = None 
    def handle(self): 
     data = self.request[0].strip()   
     # (...) 
     self.PLAYER_BOX.foo() 

class ServerManager(): 

    def __init__(self, player_box): 
     class ThreadedUDPRequestHandlerWithPlayerBox(ThreadedUDPRequestHandler): 
      PLAYER_BOX = player_box 
     HOST, PORT = "xxx.xxx.xxx.xxx", 9999 
     self.server = ThreadedUDPServer((HOST, PORT), ThreadedUDPRequestHandlerWithPlayerBox) 

Как вы можете видеть, идея имеет два детали:

  1. Пусть у вашего класса обработчика есть атрибут класса, к которому будут доступны его методы.
  2. Создайте подклассы этого класса, где вышеуказанный атрибут будет установлен в желаемое значение (в вашем случае - объект player_box).

Надеюсь, это поможет.

+0

Это неплохая идея. Однако компилятор жалуется на PLAYER_BOX, не имея метода foo, потому что он имеет тип None, и, думаю, для этого было бы более уродливо. В любом случае, на грани отчаяния, я бросился в объятия Твист. Я считаю, что потоки в структуре ServerSocket немного странны. Спасибо за предложение. – broncoAbierto

+0

Я никогда не использовал Twisted, но выглядит очень красиво. Если вы все-таки решите использовать вышеуказанный метод, вы можете использовать 'if self.PLAYER_BOX не None: self.PLAYER_BOX.foo()', чтобы избежать потенциальных проблем. Удачи! –

Смежные вопросы