Domanda

Sono nuovo di Python (sto programmando in Java da diversi anni ormai) e sto lavorando a una semplice applicazione di rete basata su socket (solo per divertimento). L'idea è che il mio codice si connette a un endpoint TCP remoto e quindi ascolti tutti i dati trasferiti dal server al client ed esegua un po 'di analisi su questo.

I dati inviati dal server - > il client è un testo codificato UTF-8 e ogni riga è delimitata da CRLF ( \ x0D \ x0A ). Probabilmente hai indovinato: l'idea è che il client si connetta al server (fino a quando non viene annullato dall'utente), quindi legge e analizza le righe appena entrano.

Sono riuscito a farlo funzionare, tuttavia, non sono sicuro di farlo nel modo giusto. Quindi quindi le mie domande attuali (codice da seguire):

  1. È questo il modo giusto di farlo in Python (cioè è davvero così semplice)?
  2. Eventuali suggerimenti / trucchi / risorse utili (a parte la documentazione di riferimento) riguardo ai buffer / asyncore ?

Attualmente, i dati vengono letti e bufferizzati come segue:

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 funzione ByteUtils.ends_with_crlf controlla semplicemente gli ultimi due byte del buffer per \ x0D \ x0A . La prima domanda è la principale (la risposta si basa su questo), ma ogni altra idea / consiglio è apprezzata. Grazie.

È stato utile?

Soluzione

TCP è un flusso e non si garantisce che il buffer non conterrà la fine di un messaggio e l'inizio del successivo. Pertanto, il controllo di \ n \ r alla fine del buffer non funzionerà come previsto in tutte le situazioni. Devi controllare ogni byte nello stream.

E ti consiglio vivamente di usare Twisted invece di asyncore. Qualcosa del genere (dalla memoria, potrebbe non funzionare immediatamente):

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

Altri suggerimenti

È ancora più semplice: guarda asynchat e i suoi set_terminator (e altri utili bocconcini in quel modulo). Twisted è ordini di grandezza più ricchi e più potenti, ma, per compiti sufficientemente semplici, asyncore e asynchat (che sono progettato per interagire senza problemi) sono davvero molto semplici da usare, come hai iniziato a osservare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top