Frage

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()
War es hilfreich?

Lösung

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!

Andere Tipps

The only "id" that you can get from sockets directly is the reference to the socket and the sender's address. Everything else is based on the data that you receive - your client could e.g. send its id as the first 16 bytes, anything after that would be data. This means effectively implementing a protocol that fulfills your requirements.

An easier and better solution for authentication etc. is to use some library such as ssl in python standard library. The ssl library provides encryption and authentication mechanisms in a form that can easily be used with python sockets. If you have any need for secure authentication, I strongly recommend using existing solutions.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top