La lettura da un flusso telnet in un array di byte di grandi dimensioni attende che l'array di byte sia pieno?

StackOverflow https://stackoverflow.com/questions/810963

  •  03-07-2019
  •  | 
  •  

Domanda

Dalla lettura di alcune domande e risposte qui, sembra che un flusso di telnet non si chiuda davvero. L'uso di DataAvailable () non restituirà.

Ho ereditato del codice che ha richiesto molto tempo per essere completato e abbiamo pensato che fosse il server Telnet a costituire il problema. Tuttavia, esiste un byte [32757] in cui il codice tenta di memorizzare la risposta del server Telnet.

Qualcosa di simile al seguente:

Byte byteArray[] = new Byte[32757];
TcpClient sock = new TcpClient();
sock.GetStream().read(byteArray, 0 byteArray.length);

Se non ci sono 32757 byte o più, suppongo che questo codice aspetti fino a quando non vengono inviati abbastanza pacchetti vuoti per compensare la dimensione dell'array di byte. È corretto?

C'è un modo per verificare se il server Telnet ha finito di inviare tutto ciò che vuole? Non ci sono caratteri o stringhe di chiusura visibili in ogni "pagina" della sessione telnet.

Stavo pensando che un modo per correggere questo codice è leggere alcuni byte alla volta, aggiungerlo a una stringa, controllare la stringa per un carattere che termina o un set di caratteri e restituire se trovato. Altrimenti, leggi più byte, aggiungilo alla stringa e ricontrolla.

Suggerimenti?

È stato utile?

Soluzione

No, Stream.Read in genere non attende fino a quando non viene letto tutto ed è anche meno probabile che si verifichi un flusso di rete. Leggerà tutti i dati disponibili o si bloccherà fino a quando non saranno disponibili alcuni , ma è tutto.

Non esiste un vero concetto del server "finitura". inviare ciò che sta per inviare, a meno che:

  • a) ti dice in anticipo quanto invierà
  • b) indica quando ha finito con una sorta di dati di terminazione
  • c) chiude la connessione

Potresti voler usare un timer di qualche tipo per ottenere un effetto di "continua a leggere fino a quando una delle letture impiega più di 5 secondi". Tieni presente che la lettura continuerebbe comunque: sceglieresti quel momento per aggiornare l'interfaccia utente (o qualsiasi altra cosa). È un argomento piuttosto complicato e devi davvero essere molto chiaro nella tua mente (e documenti!) Cosa vuoi fare e quale thread gestirà cosa.

Un'alternativa è impostare un timeout di lettura su TcpClient , ma non ne ho esperienza. Probabilmente avresti solo bisogno di usare TcpClient.ReceiveTimeout e quindi gestire IOException risultante in modo appropriato durante la lettura, ma non ho alcun consiglio da offrire al riguardo.

Altri suggerimenti

Oltre alla spiegazione di Jon Skeets un piccolo suggerimento:

poiché telnet è un protocollo basato su testo (riga), la lettura in byte [] significa che dovrai riassemblare il testo. Starai meglio con un TextReader:

System.IO.TextReader reader = new System.IO.StreamReader(
           sock.GetStream(), Encoding.ASCII);
string line;
while ((line = reader.ReadLine()) != null)  ...;

Sto indovinando qui che Telnet utilizza ASCII.

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