Pergunta

Eu sou novo para Python (eu tenho sido programação em Java para vários anos embora), e eu estou trabalhando em um aplicativo de rede baseada em soquete simples (apenas para se divertir). A ideia é que os meus Ligações código a um ponto final TCP remoto e escuta para quaisquer dados que estão sendo empurrados a partir do servidor para o cliente, e realizar alguma análise sobre este assunto.

Os dados que estão sendo empurrado de servidor -> cliente é UTF-8 texto codificado, e cada linha é delimitada por CRLF (\x0D\x0A). Você provavelmente já adivinhou:. A idéia é que o cliente se conecta ao servidor (até ser cancelada pelo usuário) e, em seguida, lê e analisa as linhas que eles chegam

Eu consegui chegar a este trabalho, no entanto, não tenho certeza que eu estou fazendo isso bastante da maneira certa. Assim, portanto, minhas perguntas reais (código a seguir):

  1. Este é o caminho certo para fazê-lo em Python (ie. É realmente este simples)?
  2. Qualquer dicas / truques / recursos úteis (para além da documentação de referência) sobre buffers / asyncore?

Atualmente, os dados estão sendo lidos e tamponada a seguinte:

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

A função ByteUtils.ends_with_crlf simplesmente verifica os dois últimos bytes do buffer para \x0D\x0A. A primeira pergunta é a principal (resposta é baseada sobre isso), mas outras ideias / sugestões são apreciadas. Obrigado.

Foi útil?

Solução

O TCP é um fluxo, e você não está garantido que o buffer não irá conter o final de uma mensagem eo início da próxima. Assim, a verificação de \ n \ r no final do buffer não vai funcionar como esperado em todas as situações. Você tem que verificar cada byte no fluxo.

E, eu recomendo fortemente que você use trançado em vez de asyncore. Algo como isso (a partir da memória, não pode trabalhar fora da caixa):

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

Outras dicas

É ainda mais simples - olhada asynchat e sua método set_terminator (e outros petiscos votos nesse módulo). torcida é ordens de magnitude mais rico e mais poderoso, mas, para tarefas suficientemente simples, asyncore e asynchat (que são projetado para interoperar sem problemas) são realmente muito simples de usar, como você começou a observar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top