Прежде чем перейти к подробному описанию работы функции select (), рассмотрим новую версию клиента “gab” в виде сценария gab5.pl, предназначенную для поддержки мультиплексирования, которая, как и предыдущее ее воплощение, принимает строки со стандартного ввода, передает их на удаленный сервер, а затем перенаправляет ответ от сервера в стандартный вывод. Проведем краткий обзор данного сценария.
1) Создание нового набора объектов IO::Select. Принято решение мультиплексировать операции чтения из стандартного ввода и сокета. Это значит, что чтение из стандартного ввода будет выполняться, только если пользователь ввел некоторые данные, а чтение из сокета — только если есть данные, переданные сервером и доступные для чтения.
Для этого создается новый объект IO::Select путем вызова метода IO::Select->new(). Объект IO::Select содержит один или несколько дескрипторов файлов, которые позволяют проверять их готовность к выполнению ввода-вывода. После создания объекта IO::Select в него вводятся дескрипторы файла stdin и сокета путем вызова метода add( ) этого объекта.
2) Главный цикл ввода-вывода. Теперь программа входит в цикл while (). При каждом проходе по циклу вызывается метод can_read () объекта IO::Select для чтения списка дескрипторов, готовых для чтения. Этот список может содержать дескриптор сокета, дескриптор файла stdin или оба дескриптора. Задача состоит в просмотре в цикле списка готовых дескрипторов и выполнении соответствующего действия для каждого из них. Если готов для чтения дескриптор stdin, данные из него копируются в сокет. Если готов сокет, данные из него копируются в дескриптор stdout.
3) Обработка данных в дескрипторе stdin. Если дескриптор stdin готов для чтения, то применяется функция sysread () для чтения, вплоть до 2 Кбайт, данных в строковую переменную $buffer. Если функция sysread () возвращает положительное значение, копия полученных данных записывается в сокет. В ином случае это значит, что в стандартном вводе появился признак конца файла. Выполняется функция shutdown () для закрытия той половины сокета, которая предназначена для записи, и на удаленный сервер отправляется признак конца файла.