2012-05-15 2 views
1

Я пишу простой сервер сокетов, и я хочу отслеживать состояние клиентов (аутентификация и прочее). Каждый раз, когда вызывается handle_read(), я ничего не знаю об этом конкретном клиенте. Это помогло бы, если бы я знал идентификатор клиента или что-то в этом роде. Вот то, что я до сих пор:python asyncore отслеживает клиентов

import asyncore 
import socket 

class EchoHandler(asyncore.dispatcher_with_send): 

    def handle_read(self): 
     data = self.recv(8192) 
     self.send(data) 

class EchoServer(asyncore.dispatcher): 

    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is None: 
      pass 
     else: 
      sock, addr = pair 
      print 'Incoming connection from %s' % repr(addr) 
      handler = EchoHandler(sock) 

server = EchoServer('localhost', 8080) 
asyncore.loop() 

ответ

4

Вы знаете идентификатор клиента, когда получаете соединение от repr(addr). Возвращенный кортеж - это IP-адрес и уникальный номер для этого клиента, который может использоваться, когда вы хотите отправить данные обратно этому клиенту. Если вы хотите сохранить список клиентов, вы должны рассмотреть словарь, который при приеме входящего соединения сохраняет информацию этого клиента.

Если вы хотите, чтобы информация передается в функцию handle_read, ваш код будет выглядеть примерно так, как показано ниже:

class EchoHandler(asyncore.dispatcher_with_send): 
    def setAddr(self, addr): 
     self.addr = addr 

    def handle_read(self): 
     data = self.recv(8192) 
     print '%s from %s' % (data, self.addr) 
     self.send(data) 

class EchoServer(asyncore.dispatcher): 

    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is None: 
      pass 
     else: 
      sock, addr = pair 
      print 'Incoming connection from %s' % repr(addr) 
      handler = EchoHandler(sock) 
      handler.setAddr(addr) #Set the address of the sender in the EchoHandler 

Просто отправьте адрес клиента EchoHandler, и теперь вы знаете, где он и откуда. Надеюсь, что это помогает/работает!

+0

То, что мне нужно, спасибо! –

1

Единственный «идентификатор», который вы можете получить от розетки непосредственно является ссылка на сокет и адрес отправителя. Все остальное зависит от данных, которые вы получаете - ваш клиент может, например, отправьте свой идентификатор в качестве первых 16 байтов, после чего будут данные. Это означает эффективное внедрение протокола, который соответствует вашим требованиям.

Простым и лучшим решением для аутентификации и т. Д. Является использование некоторой библиотеки, такой как ssl в стандартной библиотеке python. Библиотека ssl обеспечивает механизмы шифрования и аутентификации в форме, которая может быть легко использована с сокетами python. Если вам нужна безопасная аутентификация, я настоятельно рекомендую использовать существующие решения.

+0

Адреса отправителей будет достаточно. Как я могу получить это в функции handle_read()? Реализация моего собственного протокола не может быть и речи, поскольку он должен работать с существующими устройствами. –

+0

Как сказано в ответе @ Cryptite, у вас есть адрес от вызова 'accept()' как seconf part 'pair'. Вы можете получить его в 'handle_read()' либо путем создания конструктора, либо для отдельного метода установки для EchoHandler и сохранения его в классе. – jhonkola

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