Основа клиента TELNET

Опубликовано в Технологии > Серверные технологии

После вызова клиентская программа выполняет необходимую инициализацию. Затем клиентская программа входит в бесконечный цикл, в котором применяется функция select для перехода в состояние ожидания готовности дескрипторов к вводу/выводу. Код клиентской программы содержится в файле telnet.с. Для вакуумного массажа.

Процедура telnet принимает два параметра с указанием имени удаленного компьютера и службы на этом компьютере. Код начинается с вызова функции connectTCP для распределения сокета и формирования соединения TCP с сервером. В этой процедуре вызывается процедура ttysetup для инициализации параметров локального терминала и процедура f smbuild — для инициализации трех конечных автоматов. Затем в ней вызывается системная функция signal, создающая дескриптор для срочных данных. Если программное обеспечение TCP получит срочные данные от сервера после вызова на нем функции signal, операционная система вызовет для их обработки процедуру rcvurg.

Для обеспечения переносимости кода в данной реализации не определено максимальное число дескрипторов файлов. Вместо этого перед инициализацией дескрипторов файлов в процедуре telnet вызывается системная функция getdtablesize для определения числа дескрипторов файлов, доступных в системе, после чего выполняется регистрация полученного результата в переменной nfds. При каждом проходе по главному циклу процедура telnet передает это значение в качестве первого параметра функции select.

Поскольку процедуры tcdm и rcvurg являются весьма небольшими, они не были помещены в отдельные файлы. Вместо этого код обеих процедур включен в файл sync.с:

/* Файл sync - процедуры tcdm, rcvurg */ include 
char    synching;    /* Отличен от нуля, если происходит синхронизация TELNET */

Протокол TELNET указывает, что при получении срочных данных клиент должен выполнить синхронизацию своего состояния с сервером. Для синхронизации клиент пропускает все символы в потоке данных, поступающих с сервера до тех пор, пока не встретит символ DATA MARK. Таким образом, при получении сигнала срочных данных процедура rcvurg просто наращивает значение глобальной переменной synching для перевода клиентской программы в режим синхронизации. После установки переменной synching исполнительные процедуры конечного автомата просто отбрасывают входящие данные, не отображая их на экране терминала пользователя. В дальнейшем после поступления символа DATA MARK клиент вызывает процедуру tcdm, чтобы снова присвоить глобальной переменной synching нулевое значение, после чего клиентская программа возвращается в режим нормальной обработки.

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

При нормальном возврате управления из функции select в программе могут быть приняты данные, введенные с клавиатуры, поступившие из сокета или полученные из того или иного устройства ввода. Процедура telnet вначале проверяет сокет для определения того, имеются ли данные, поступившие с сервера. Если такие данные имеются, в процедуре вызывается функция read для получения данных и функция ttwrite — для вывода данных на экран терминала пользователя. Как будет показано ниже, в процедуре ttwrite реализована принципиальная схема конечного автомата, который интерпретирует входящий поток данных и обрабатывает управляющие символы и встроенные управляющие последовательности.

После проверки наличия входящих данных в сокете процедура telnet проверяет дескриптор клавиатуры. Если данные поступили с клавиатуры, в процедуре telnet вызывается функция read для получения данных и процедура sowrite — для вывода их в сокет. Процедура sowrite содержит код, вызывающий на выполнение конечный автомат, предназначенный для локальной обработки управляющих символов. В отдельных случаях клиент интерпретирует признак конца файла как запрос на прекращение соединения. При получении признака конца файла (т.е. при возврате функцией read значения 0) процедура telnet вызывает процедуру shutdown для передачи признака конца файла на сервер. В любом случае в процедуре telnet при каждом проходе по циклу вызывается функция fflush для обеспечения того, чтобы процедуры вывода не хранили в буфере выведенные данные. Функция fflush активизирует вызов системной процедуры write.