Como posso usar o Telnetlib do Python para buscar dados de um dispositivo por um período fixo de tempo?
Pergunta
Estou me conectando a um dispositivo de hardware via telnet. Esse dispositivo é bastante simples em termos de E/S. Por isso, enviei um comando para ele e, depois disso, o dispositivo bombeia dados uma linha de cada vez, uma vez por segundo. Cada linha contém apenas um número.
Então, minha pergunta é a seguinte: se eu conectar a este dispositivo usando o Telnetlib do Python, como posso buscar dados por um período fixo de tempo (ou um número fixo de linhas de dados)?
Eu tentei usar todos os vários comandos READ_, mas todos parecem bloquear indefinidamente, além de read_until, que não posso usar, pois a saída não pode ser usada para determinar quando parar.
(Estou executando o Python 2.5 sob Cygwin, btw).
EDIT: Talvez a verdadeira pergunta seja: devo usar o Telnetlib para isso, ou devo apenas usar o módulo de soquete?
Solução
Pela sua descrição, não estou claro se você está usando Telnetlib porque o dispositivo que você está se conectando requer configuração de terminal fornecida pela telnet Ou porque parecia a coisa certa a fazer.
Se o dispositivo é tão simples quanto você descrever-não negocia opções de terminais na conexão-você considerou o Asynchat módulo? Seria apropriado para o tipo de padrão "Send Comando, Leia Linhas" que você está descrevendo.
Alternativamente, para algo de nível inferior, você pode usar o soquete módulo para abrir a conexão com o dispositivo e depois sentar em um loop cronometrado e read()
os dados recebidos. Se as linhas tiverem terminado em linha nova, deve ser simples para você identificar cada número individual. Se você estiver preocupado com o bloqueio, coloque esse loop em seu próprio tópico.
Outras dicas
Parece que bloquear não é realmente o seu problema, já que você sabe que você só estará bloqueando por um segundo. Por que não fazer algo como:
lines_to_read = 10
for i in range(lines_to_read):
line = tel.read_until("\n")
Na minha experiência, a maioria desses dispositivos usa algum rápido, nesse caso Telnet.read_until()
é apropriado:
Telnet.read_until(expected[, timeout])
Leia até que uma determinada string, esperada, seja encontrada ou até que os segundos de tempo limite se passarem. Quando nenhuma correspondência for encontrada, retorne o que estiver disponível, possivelmente a string vazia. Aumente o Eoperror se a conexão estiver fechada e nenhum dado cozido estará disponível.
Se nenhum prompt utilizável (repetitivo) for apresentado pelo dispositivo, tente Telnet.read_very_eager()
, ou Telnet.read_very_lazy()
:
Telnet.read_very_eager()
Leia tudo o que pode ser sem bloquear em E/S (ansioso).
Aumente o Eoperror se a conexão fechada e não há dados cozidos disponíveis. Retorne '' se não houver dados cozidos disponíveis de outra forma. Não bloqueie a menos que no meio de uma sequência IAC.
Leia as linhas em um loop até que você leia o número necessário de linhas ou o limite de tempo tenha sido atingido. No entanto, não parece que você precisa de uma biblioteca Telnet. Por que não usar apenas um TCP simples soquete para a conexão?