Прототип к варианту 7 - Использование именованных каналов
В примере с именованными каналами встречаются многие приемы, упоминавшиеся в этой главе. Прежде всего в нем продемонстрирован обмен данными через именованные каналы — как локально, так и по сети. Кроме того, он показывает, как выполнять асинхронную пересылку данных с применением перекрывающихся операций записи, расширяя пример Async.vbp из главы 13.
Программа PipeSrv создает именованный канал, в который любой подключившийся канал может записать данные. В программе имеется таймер, который периодически увеличивает счетчик и выводит его обновленное значение. Счетчик является признаком того, что главная нить приложения продолжает работать.
На форме приложения находятся три кнопки, соответствующие разным режимам пересылки данных, и надпись для вывода информации о текущем состоянии (рис. 1). При нажатии каждой кнопки приложение пересылает блок из 200 байтов, который читается клиентским приложением по одному байту (чтобы замедлить процесс и таким образом подчеркнуть разницу между разными типами пересылки данных). Проект PipeSrv будет успешно работать только в Windows NT, поскольку Windows 95 не позволяет создавать именованные каналы. Программа PipeClnt работает на обеих платформах.
Проект состоит из одной формы, PIPESRV.FRM, и модуля PIPE.ВАЗ из предыдущего примера. Программный код формы PIPESRV.FRM приведен в листинге 14.9.
Рис. 1. Главная форма проекта PipeSrv
В приложении встречаются два примера асинхронной пересылки данных с применением структуры OVERLAPPED. Чтобы избежать путаницы, при этом используются разные структуры.
Dim ol As OVERLAPPED Dim ol2 As OVERLAPPED Dim callbackobj As Object
Именованный канал создается во время загрузки приложения. Канал должен создаваться в локальной системе. В нашем примере создается однонаправленный канал, предназначенный только для передачи данных от сервера к клиенту (PIPE_ACCESS_OUTBOUND). Именованные каналы также могут создаваться в дуплексном (двунаправленном) режиме. Канал открывается в перекрывающемся режиме (FILE_FLAG_OVERLAPPED); это означает, что канал поддерживает асинхронную пересылку данных (хотя она и не является обязательной). В нашем примере используется канал байтового типа. При выгрузке приложения манипулятор канала закрывается.
Таймер в этом приложении решает две задачи. Прежде всего он увеличивает счетчик и выводит его значение в надписи Labell. Изменение счетчика показывает, что первичная нить активна и допускает обработку событий. В примере sndAsync для управления фоновой пересылкой данных используется структура OVERLAPPED. Признаком пересылки данных является то, что объект ol.hEvent существует (отличен от нуля) и еще не находится в установленном состоянии. Таймер проверяет это условие и следит за переходом события в установленное состояние, свидетельствующее о завершении пересылки данных. В этом случае манипулятор события закрывается (что приводит к удалению объекта события), а надпись возвращается в исходное состояние, говорящее о том, что канал не используется.
Функция sndBlocked_Click выполняет синхронную пересылку данных. Сначала она вызывает функцию ConnectNamedPipe, которая ждет подключения клиента к каналу. В этом приложении перед вызовом ConnectNamedPipe проследите за тем, чтобы приложение PipeClnt было запущено и подключено к каналу. Функция WriteFile возвращает управление лишь после записи всех 200 байтов, на что может потребоваться некоторое время. Вы сами увидите, что на время пересылки данных счетчик Labell перестает увеличиваться, что говорит о блокировке выполнения нити.
Функция sndAsync_Click создает для структуры OVERLAPPED событие, которое является дополнительным признаком пересылки данных. Функция WriteFile возвращает управление немедленно, а пересылка данных продолжается в фоновом режиме. Во время этой операции счетчик в надписи Labell продолжает увеличиваться.
Функция cmdAsyncZ практически идентична sndAsync. Единственное отличие заключается в том, что завершение пересылки обозначается
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.