Как программно бороться с задержками при соединении telnet?

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

Вопрос

Я использую класс 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»?

Сначала определите, разрывает ли сервер соединение после завершения передачи.Если да, то вы можете просто прочитать поток до конца.В противном случае вам придется использовать сигнал в данных, чтобы определить, завершено ли чтение.В этом отношении разные протоколы работают по-разному, поэтому, если вы расскажете нам о протоколе, мы сможем дать более прямой ответ.Подходы обычно делятся на два лагеря:включая количество байтов/символов в начале ответа (получатель просто читает это количество байтов/символов) или же использование маркера для ограничения конца ответа (получатель читает до тех пор, пока не получит разделитель).

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