Search code examples
pythonsocketsasyncore

python asyncore keep track of clients


I'm writing a simple socket server and I want to keep track of the clients state (authentication and stuff). Every time handle_read() is called I don't know anything about that particular client. It would help if I knew the ID of the client or something. Here's what I have so far:

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()

Solution

  • You do know the ID of the client when you receive the connection from the repr(addr). The tuple returned is an IP and a unique number to that client that can be used when you want to send data back to that client. If you wanted to keep a list of clients, you should consider a dictionary that, when receiving an incoming connection, stores that client's information.

    If you wanted that information passed on to the handle_read function, your code would look something like below:

    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
    

    Simply send the address of the client to EchoHandler, and now you know where it's coming from. Hope this helps/works!