SocketServer ThreadingTCPServer и диспетчер Asyncore

Я хочу добавить тайм-аут для отдельных соединений в моем обработчике запросов для сервера с помощью модуля SocketServer.

Позвольте мне начать с того, что я впервые пытаюсь программировать сети с помощью Python. Я создал подклассы SocketServer.BaseRequestHandler и SocketServer.ThreadingTCPServer и SocketServer.TCPServer, и мне удалось создать два класса с некоторыми базовыми функциями TCP с многопоточностью.

Однако я хотел бы, чтобы мои входящие соединения были тайм-аутом. Попытка переопределить любое из встроенных значений времени ожидания и методов SocketServer не работает, поскольку в документации говорится, что это работает только с разветвленным сервером. Мне удалось создать поток таймера, который срабатывает через X секунд, но из-за характера блокирующего вызова recv в потоке обработчика это бесполезно, так как я был бы вынужден его убить, и это то, что я действительно хотите избежать.

Насколько я понимаю, мне нужна асинхронная реализация, в которой я получаю уведомления и читаю определенный объем данных. В случае, если данные не отправляются в течение 5 секунд, скажем, я хочу закрыть это соединение (я знаю, как это сделать). Я нашел несколько примеров использования asyncore с сокетами, но ни один из них не использует SocketServer. Итак, как я могу реализовать asyncore и threadingTCPserver? Является ли это возможным? Кто-нибудь сделал это?


person Ælex    schedule 20.09.2012    source источник
comment
Вы можете сделать что-то таким образом, но я рекомендую изучить более простой и эффективный подход — twistedmatrix.com — и добро пожаловать в мир сетевого программирования Python! :)   -  person Jean-Paul Calderone    schedule 20.09.2012
comment
Жан-Поль Кальдероне спасибо за ссылку. Я видел это раньше. И в обычных обстоятельствах я бы выбрал скрученную матрицу, но это проект для клиента, который очень заботится о безопасности и не хочет использовать библиотеки с открытым исходным кодом или сторонние библиотеки.   -  person Ælex    schedule 20.09.2012
comment
Это очень печально, и логика неверна (Python с открытым исходным кодом и третьей стороной). Однако удачи вашему проекту.   -  person Jean-Paul Calderone    schedule 21.09.2012


Ответы (1)


Вы также можете установить тайм-аут для вызова recv, например:

sock.settimeout(1.0)

Поскольку вы используете SocketServer, вам придется найти базовый socket где-то в SocketServer. Обратите внимание, что SocketServer создаст для вас сокет, поэтому нет необходимости делать это самостоятельно.

Вы, вероятно, определили RequestHandler для своего SocketServer. Это должно выглядеть примерно так:

class RequestHandler(SocketServer.BaseRequestHandler):
    def setup(self):
         # the socket is called request in the request handler
         self.request.settimeout(1.0)

    def handle(self):
         while True:
             try: 
                 data = self.request.recv(1024)
                 if not data:
                      break # connection is closed
                 else:
                      pass  # do your thing
             except socket.timeout:
                 pass # handle timeout
person Hans Then    schedule 20.09.2012
comment
Я не могу заставить это работать, к сожалению. Я пытался (внутри обработчика запросов) сделать: sock = self.server.socket(socket.AF_INET, socket.SOCK_STREAM) sock = self.request.socket(socket.AF_INET, socket.SOCK_STREAM) Каждый раз, когда я это делаю , соединение просто не работает - person Ælex; 20.09.2012
comment
Большое спасибо ! это работает с ForkingTCPServer, делает именно то, что я хотел. Проверим его с помощью ThreadingTCPServer и посмотрим, работает ли он и там. Еще раз спасибо !!! - person Ælex; 20.09.2012