Ожидает ли чтение из потока telnet в большой байтовый массив ожидание заполнения байтового массива? - PullRequest
0 голосов
/ 01 мая 2009

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

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

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

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

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

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

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

Предложения

Ответы [ 2 ]

4 голосов
/ 01 мая 2009

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

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

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

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

3 голосов
/ 01 мая 2009

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

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

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

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

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

...