Question

Je connais Python pour la première fois (cependant, je programme en Java depuis plusieurs années maintenant) et je travaille sur une simple application réseau basée sur des sockets (juste pour le plaisir). L'idée est que mon code se connecte à un point de terminaison TCP distant, puis écoute toutes les données envoyées du serveur au client et effectue une analyse syntaxique.

Les données envoyées du serveur - > le client est du texte codé UTF-8 et chaque ligne est délimitée par CRLF ( \ x0D \ x0A ). Vous l'avez probablement deviné: l'idée est que le client se connecte au serveur (jusqu'à ce qu'il soit annulé par l'utilisateur), puis lit et analyse les lignes au fur et à mesure de leur arrivée.

J'ai réussi à faire en sorte que cela fonctionne, cependant, je ne suis pas sûr de le faire de la bonne façon. D'où mes vraies questions (code à suivre):

  1. Est-ce la bonne façon de le faire en Python (c'est-à-dire si simple?)
  2. Tous les conseils / astuces / ressources utiles (en dehors de la documentation de référence) concernant les tampons / asyncore ?

Actuellement, les données sont en cours de lecture et de mise en mémoire tampon comme suit:

def handle_read(self):
    self.ibuffer = b""

    while True:
        self.ibuffer += self.recv(self.buffer_size)
        if ByteUtils.ends_with_crlf(self.ibuffer):
            self.logger.debug("Got full line including CRLF")
            break
        else:
            self.logger.debug("Buffer not full yet (%s)", self.ibuffer)

    self.logger.debug("Filled up the buffer with line")
    print(str(self.ibuffer, encoding="UTF-8"))

La fonction ByteUtils.ends_with_crlf vérifie simplement les deux derniers octets du tampon pour \ x0D \ x0A . La première question est la principale (la réponse est basée sur celle-ci), mais toute autre idée / astuce est appréciée. Merci.

Était-ce utile?

La solution

TCP est un flux, et rien ne garantit que votre tampon ne contiendra pas la fin d’un message ni le début du suivant. Ainsi, la recherche de \ n \ r à la fin du tampon ne fonctionnera pas comme prévu dans toutes les situations. Vous devez vérifier chaque octet dans le flux.

Et je vous recommande fortement d'utiliser Twisted au lieu d'asyncore. Quelque chose comme ça (de mémoire, cela pourrait ne pas fonctionner immédiatement):

from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver


class MyHandler(LineReceiver):

    def lineReceived(self, line):
        print "Got line:", line


f = protocol.ClientFactory()
f.protocol = MyHandler
reactor.connectTCP("127.0.0.1", 4711, f)
reactor.run()

Autres conseils

C'est encore plus simple: consultez asynchat et ses set_terminator (ainsi que d'autres informations utiles dans ce module). Twisted est un ordre de grandeur plus riche et plus puissant, mais, pour les tâches suffisamment simples, asyncore et asynchat (qui sont conçus pour interagir en douceur) sont en effet très simples à utiliser, comme vous avez commencé à les observer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top