2 votes

Python async socket recv ne fonctionne pas

Voici un client simple qui se connecte et envoie un message texte :

class Client(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.connect( (host, port) )
        self.buffer = bytes("hello world", 'ascii')

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print(self.recv(8192))

    def writable(self):
        return (len(self.buffer) > 0)

    def writable(self):
        return True

    def handle_write(self):
        sent = self.send(self.buffer)
        print('Sent:', sent)
        self.buffer = self.buffer[sent:]

client = Client('localhost', 8080)
asyncore.loop()

Et voici le serveur qui doit recevoir le message et le renvoyer :

class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_read(self):
        self.buffer = self.recv(4096)
        while True:
            partial = self.recv(4096)
            print('Partial', partial)
            if not partial:
                break
            self.buffer += partial

    def readable(self):
        return True

    def handle_write(self):
        pass

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        self.handle_read()
        print(self.buffer)

if __name__ == "__main__":
    server = Server("localhost", 8080)
    asyncore.loop()

Le problème est que le serveur ne lit rien. Lorsque j'imprime self.buffer, la sortie est la suivante :

b''

Qu'est-ce que je fais de travers ?

1voto

phihag Points 89765

Tout d'abord, vous avez besoin de deux gestionnaires : un pour le socket du serveur (où l'on s'attend à ce que seulement accept ), et un autre pour les sockets de communication proprement dits. En outre, vous ne pouvez appeler que read une fois dans handle_read ; si vous l'appelez deux fois, le deuxième appel risque d'être bloqué, ce qui n'est pas autorisé dans la programmation asynchrone. Ne vous inquiétez pas cependant ; si votre lecture n'a pas tout obtenu, vous serez immédiatement notifié à nouveau une fois que votre gestionnaire de lecture reviendra.

import asyncore

class Handler(asyncore.dispatcher):
    def __init__(self, sock):
        self.buffer = b''
        super().__init__(sock)

    def handle_read(self):
        self.buffer += self.recv(4096)
        print('current buffer: %r' % self.buffer)

class Server(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        Handler(sock)

if __name__ == "__main__":
    server = Server("localhost", 1234)
    asyncore.loop()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X