Статьи Королевства Дельфи

Сервер удаленного доступа. Часть II


Раздел Подземелье Магов Автор Александр Галилов
дата публикации 11 ноября 1999г.

Предисловие ко второй части

В первой части статьи был рассмотрен пример построения внутрисистемного интерфейса сервера удаленного доступа. К сожалению, неожиданно стали очевидными некоторые моменты, делающие использование DLL нежелательным. Во-первых, метод Synchronize далеко не всегда нормально работает в нитях (threads), созданных внутри DLL. Т.е. при вызове Synchronize(Something) метод Something не запускается. Этот эффект наблюдается только при использовании DLL и очевиднее всего именно в Win NT, что и послужило основной причиной неработоспособности примера в этой ОС. Во-вторых в Win 95/98 также есть ряд условий, отличных от таковых в Win NT, при которых Synchronize внутри DLL работает неправильно. В силу сложившихся обстоятельств в новом примере предоставляю исходник DLL, не использующей вышеупомянутый метод. Однако, при ее использовании остается проблема синхронизации с "main VCL thread". Мною были также исправлены "глюки" с обработкой очередей в предыдущей версии DLL и дополнен заголовочный файл. В-третьих, учитывая дополнительную сложность использования функций DLL для доступа к ее нитям, я решил подготовить новый пример полнофункционального (с "натягом", конечно) сервера без использования каких бы то ни было DLL. Все принципы, описанные в первой части, в примере реализованы полностью. В ходе этой работы замечены некоторые особенности работы компонента TServerSocket, которые Вы заметите, если начнете с ним активно "общаться". Но это уже так, к слову.

Введение
Обеспечение обслуживания клиентов - неотъемлемая функция любого сервера удаленного доступа. Рассмотренный здесь пример не является исключением. Обслуживание клиента состоит из четырех основных стадий:

  1. Аутентификация при подключении клиента;
  2. Подготовка рабочей среды, т.е. выделение ресурсов на обслуживание;
  3. Собственно процесс обслуживания, состоящий в выполнении клиентских запросов и отсылке сообщений о результатах;
  4. Отключение клиента и освобождение выделенных ресурсов;
В качестве главного "интернетовского компонента" используется TServerSocket, позволяющий осуществлять многоканальное обслуживание.


Аутентификация
В данном случае аутентификация заключается в запросе пароля у пользователя и проверке правильности введенного слова. Процесс аутентификации реализован в виде отдельной нити, внутри которой происходит циклический опрос сокета пользователя на предмет наличия введенных символов. Время опроса и длина вводимой цепочки символов ограничена соответственно 30 секундами и 32 символами. Символы с кодом менее 32 (пробел) считаются признаком конца строки. После того, как пароль будет введен, выполняется проверка введенного слова на наличие в списке допустимых паролей. Если список не содержит такого слова, то пользователю отправляется сообщение о неудачной попытке и связь разрывается, после чего завершается и сама нить. В случае правильного ввода пароля происходит инициализация другой нити, производящей запуск ДОСовской сессии или подключение к уже запущенной сессии.

Выделение ресурсов
Для выделения ресурсов используется нить внутри которой происходит запуск командного интерпретатора. Сразу же после запуска инициализируются нити ввода-вывода данных, а управляющая нить переходит в режим ожидания завершения работы командного интерпретатора. Каждая сессия имеет специальную структуру-описатель, в которой храниться состояние соединения, ссылка на сокет клиента и ссылка на нить, запустившую командный интерпретатор. Указатель на эту структуру храниться в списке пользователей и паролей который, в свою очередь, заполняется информацией при инициализации программы-сервера на основании файла PASSWORDS.LST (см. пример). Сама структура формируется непосредственно перед активизацией сессии.

Обслуживание
Обслуживание клиентов происходит следующим образом: обработчик события, возникающего при поступлении информации от клиента, направляет поступающие данные (символы, строки) на входную очередь нити которая переносит данные через трубку (pipe) в командный интерпретатор или в запущенную из него программу на стандартное устройство ввода (STDIN). Для того, чтобы поступающие данные попадали в требуемый сеанс MS-DOS, сокет-источник данных сравнивается с сокетом в структуре-описателе сесии (см. предыдущий параграф). Когда командный интерпретатор или запущенная из него программа пытается осуществить вывод символов на стандартное устройство вывода (STDOUT) происходит передача символов через трубку в нить, контролирующую выходящий из сеанса MS-DOS поток. Эта нить вызывает Call-back функцию которая на основании данных из структуры-описателя осуществляет передачу информации через требуемый сокет.

Отключение клиента
Отключение клиента осуществляется либо по инициативе клиента, либо по инициативе администратора, либо в результате сбоя в канале обмена данными. Если клиент завершил свою сессию командой EXIT, то ожидающая завершения командного интерпретатора нить сама инициализирует процесс завершения соединения. Во всех этих случаях механизм реализации отсоединения одинаков. Просто-напросто производится завершение соединения на требуемом сокете и изменение содержимого полей соответствующей структуры-описателя. Если же происходит завершение работы командного интерпретатора, то структура-описатель уничтожается, что свидетельствует о необходимости повторного создания сеанса MS-DOS при присоединении клиента. Если клиент отсоединился не завершив работу своего командного интерпретатора, то вся обработка, инициированная отключившимся клиентом на сервере, продолжается без участия клиента. В таком случае, при повторной установке соединения клиенту будет предоставлена та же сессия, которую он покинул, но, возможно, с продолжающимся или завершенным процессом выполнения ранее данного задания.

Пример (Delphi 3) Вы можете скачать (19 K)

Александр Галилов


Содержание раздела