Как программно бороться с задержками при соединении telnet?
Вопрос
Я использую класс TcpClient для реализации соединения Telnet.Чего я не знаю, так это как определить конец ответа.Кажется, что как только свойство DataAvailable имеет значение true, я читаю данные из Stream, а затем для DataAvailable временно устанавливается значение false, пока буфер заполняется другим фрагментом данных, но я думаю, что все прочитано и исчезло.Как убедиться, что весь ответ был прочитан?
Вы могли бы посоветовать мне, как изменить приведенный ниже фрагмент кода, чтобы все работало правильно.Он работает правильно, когда я просматриваю код, потому что времени для получения всего ответа достаточно.Ценю вашу помощь.
if (this.Stream.DataAvailable)
{
readBuffer = new Byte[this.Client.ReceiveBufferSize];
do
{
// read data
bytes = this.Stream.Read(readBuffer, 0, readBuffer.Length);
Thread.Sleep(10);
responseData = String.Concat(responseData, System.Text.Encoding.ASCII.GetString(readBuffer, 0, bytes));
} while (this.Stream.DataAvailable);
allDataRead = true;
break;
}
Решение
При TCP-соединениях для таких приложений, как Telnet, не существует такого понятия, как окончание передачи.Вы часто встретите telnet-клиентов, которые отправляют каждое нажатие клавиши по одному, когда пользователь их вводит, и сервер решает, когда предпринять действие, обычно когда он получает перевод строки.Другие клиенты могут буферизировать несколько нажатий клиентских клавиш и отправить их все сразу.
Судя по вашему приложению, вам следует искать переводы строк, обозначающие конец передачи.
do
{
bytes = this.Stream.Read(readBuffer, 0, readBuffer.Length);
responseData = String.Concat(responseData, System.Text.Encoding.ASCII.GetString (readBuffer, 0, bytes));
} while (this.Stream.DataAvailable && !responseData.Contains("\n"));
Другие советы
Я не думаю, что использовать DataAvailable для этой цели — хорошая идея.Конец вашего ответа — это то, что говорит ваш протокол.
Лучше использовать блокирующие вызовы, такие как Read, для чтения ваших данных, и использовать любой установленный вами протокол, чтобы определить, нужно ли читать больше и в каком объеме.Возможно, возвращаются не все данные, которые вам нужны, потому что Read возвращает не тогда, когда прочитаны все ваши данные, а когда прочитаны некоторые данные, поэтому вам нужно проверить, какой объем был прочитан.
Если у вас протокол Telnet, вам, скорее всего, захочется реагировать на каждый полученный байт, как в случае с терминалом, который вы хотите отобразить, или обработать команды, или что-то еще.
DataAvailable, возможно, подходит для проверки того, будет ли блокироваться чтение при вызове (он вернет все, что находится в буфере), но это делает ваш цикл менее простым.
Это фактическое соединение Telnet, т.е.вы подключаетесь к серверу telnet или под «telnet» вы действительно имеете в виду «сокет TCP/IP»?
Сначала определите, разрывает ли сервер соединение после завершения передачи.Если да, то вы можете просто прочитать поток до конца.В противном случае вам придется использовать сигнал в данных, чтобы определить, завершено ли чтение.В этом отношении разные протоколы работают по-разному, поэтому, если вы расскажете нам о протоколе, мы сможем дать более прямой ответ.Подходы обычно делятся на два лагеря:включая количество байтов/символов в начале ответа (получатель просто читает это количество байтов/символов) или же использование маркера для ограничения конца ответа (получатель читает до тех пор, пока не получит разделитель).