Será que a leitura de um fluxo de telnet em uma grande espera array de bytes até o array de bytes está cheio?
Pergunta
A partir de ler algumas perguntas e respostas aqui, parece que um fluxo de telnet nunca fecha. Usando DataAvailable () não irá retornar.
Eu herdei um código que levou muito tempo muito longo para ser concluído e nós pensamos que era o servidor telnet que era o problema. No entanto, há um byte [32757] que as tentativas de código para armazenar a resposta do servidor telnet em.
algo como o seguinte:
Byte byteArray[] = new Byte[32757];
TcpClient sock = new TcpClient();
sock.GetStream().read(byteArray, 0 byteArray.length);
Se não houver 32757 bytes ou mais, eu estou supondo que este código aguarda até pacotes vazios suficientes são enviados para compensar o tamanho da matriz de bytes. É este correto?
Existe uma maneira de verificar se o servidor telnet terminou de enviar tudo o que quer? Não há caractere de terminação visível ou string em cada 'página' da sessão telnet.
Eu estava pensando uma maneira de corrigir este código é ler alguns bytes de cada vez, acrescentar que para uma cadeia, verifique a string para um personagem de terminação ou conjunto de caracteres ea de regresso se for encontrado. Caso contrário, leia mais bytes, acrescentar que para a cadeia, e verifique novamente.
Sugestões?
Solução
Não, Stream.Read
geralmente não espere até que seja lido tudo, e é ainda menos provável que para um fluxo de rede. Ele vai ler o que os dados estão disponíveis, ou bloco até que haja alguns dados disponíveis, mas isso é tudo.
Não há nenhum conceito real do servidor "terminar" enviando o que vai enviar, a menos que:
- a) diz-lhe antecipadamente quanto vai enviar
- b) indica quando terminar com algum tipo de dados de terminação
- c) de fechar a conexão
Você pode querer usar um timer de algum tipo para conseguir um efeito de "manter a leitura até que um dos lê leva mais de 5 segundos". Note que a leitura ainda estaria acontecendo embora - você tinha acabado de pegar esse tempo para atualizar a interface do usuário (ou qualquer outro). É um tema bastante complicado, e você realmente precisa ser muito claro em sua própria mente (e docs!) O que você quer fazer, e qual thread vai lidar com o que.
Uma alternativa é definir um tempo limite de leitura na TcpClient
, mas eu não tenho experiência nisso. Você provavelmente só precisa usar TcpClient.ReceiveTimeout
e depois lidar com a IOException
resultando adequadamente ao ler, mas eu não tenho nenhum conselho a oferta sobre ele.
Outras dicas
Além de Jon Skeets explicação uma pequena dica:
desde telnet é um protocolo baseado em texto (linha), a leitura no byte [] significa que você terá que re-montar o texto. Você vai ser melhor fora com um TextReader:
System.IO.TextReader reader = new System.IO.StreamReader(
sock.GetStream(), Encoding.ASCII);
string line;
while ((line = reader.ReadLine()) != null) ...;
Eu estou supondo aqui que telnet usa ASCII.