Ожидает ли чтение из потока telnet в большой массив байтов до тех пор, пока массив байтов не заполнится?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Прочитав несколько вопросов и ответов здесь, кажется, что поток telnet на самом деле никогда не закрывается.Использование DataAvailable() не приведет к возврату.

Я унаследовал некоторый код, на выполнение которого ушло очень-очень много времени, и мы подумали, что проблема была в сервере telnet.Однако существует байт [32757], в который код пытается сохранить ответ сервера telnet.

Что-то вроде следующего:

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

Если там нет 32757 байт или больше, я предполагаю, что этот код ожидает отправки достаточного количества пустых пакетов, чтобы восполнить размер массива байт.Правильно ли это?

Есть ли способ проверить, завершил ли telnet-сервер отправку всего, что он хочет?На каждой "странице" сеанса telnet нет видимого завершающего символа или строки.

Я думал, что способ исправить этот код - прочитать несколько байт за раз, добавить это к строке, проверить строку на наличие завершающего символа или набора символов и вернуть, если найдено.В противном случае прочитайте больше байтов, добавьте их в строку и проверьте еще раз.

Предложения?

Это было полезно?

Решение

НЕТ, Stream.Read обычно не ждет, пока будет прочитано все, и это еще менее вероятно для сетевого потока.Он будет считывать любые доступные данные или блокировать их до тех пор, пока не появятся некоторые данные имеются, но это все.

Нет никакой реальной концепции того, что сервер "заканчивает" отправку того, что он собирается отправить, если только либо:

  • а) он заранее сообщает вам, сколько он собирается отправить.
  • б) это указывает, когда он будет завершен с какими-то данными завершения
  • в) это закрывает соединение

Возможно, вы захотите использовать какой-нибудь таймер для достижения эффекта "продолжайте читать, пока одно из чтений не займет более 5 секунд".Обратите внимание, что чтение все равно будет происходить - вы просто выберете это время для обновления пользовательского интерфейса (или чего-то еще).Это довольно сложная тема, и вам действительно нужно быть очень проясните в своем собственном уме (и документах!) что вы хотите сделать, и какой поток будет с чем справляться.

Альтернативой является установка тайм-аута чтения на TcpClient, но у меня нет опыта в этом.Вероятно, вам просто нужно будет использовать TcpClient.ReceiveTimeout а затем обработайте полученный IOException уместно при чтении, но у меня нет никаких советов по этому поводу.

Другие советы

В дополнение к объяснению Джона Скитса небольшой совет:

поскольку telnet - это текстовый (строчный) протокол, чтение в байтах [] означает, что вам придется заново собрать текст.Вам будет лучше с программой для чтения текстов:

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

Я предполагаю, что telnet использует ASCII.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top