Операции с именованным каналом
При первом вызове функции CreateNamedPipe сервер канала использует параметр nMaxInstances, чтобы указать максимальное количество экземпляров канала, которые могут существовать одновременно. Сервер может вызывать CreateNamedPipe многократно создавать дополнительные экземпляры канала, если оно не превышает максимальное количество экземпляров. Если функция выполнена успешно, каждый вызов возвращает дескриптор в конец сервера именованного экземпляра канала.
Как только сервер канала создает экземпляр канала, клиент канала может подключиться к нему, вызвав функцию CreateFile или CallNamedPipe. Если экземпляр канала доступен, CreateFile возвращает дескриптор в конец клиента экземпляра канала. Если экземпляры канала недоступны, клиент канала может использовать функцию WaitNamedPipe, чтобы ждать, пока канал не станет доступным.
Сервер канала может определить, когда клиент канала подключен к экземпляру канала, вызвав функцию ConnectNamedPipe. Если дескриптор канала находится в режиме блокировки ожидания, ConnectNamedPipe не возвращается до подключения клиента.
Клиенты и серверы канала могут вызывать одну из нескольких функций, а также CallNamedPipe для чтения и записи в именованный канал. Поведение этих функций зависит от типа канала и режимов, действующих для указанного дескриптора канала, как показано ниже.
- Функции ReadFile и WriteFile можно использовать с каналами типа байтов или сообщений.
- Функции ReadFileEx и WriteFileEx можно использовать с каналами типа байтов или сообщений, если дескриптор канала был открыт для перекрывающихся операций.
- Функцию PeekNamedPipe можно использовать для чтения без удаления содержимого канала типа байтов или канала типа сообщения. PeekNamedPipe также может возвращать дополнительные сведения об экземпляре канала.
- Функцию TransactNamedPipe можно использовать с дуплексными каналами типа сообщения, если дескриптор канала в вызывающий процесс установлен в режиме чтения сообщений. Функция записывает сообщение запроса и считывает ответное сообщение в одной операции, повышая производительность сети.
Сервер канала не должен выполнять операцию блокировки чтения до запуска клиента канала. В противном случае может произойти состояние гонки. Обычно это происходит при инициализации кода, например библиотеки времени выполнения C, необходимо заблокировать и проверить унаследованные дескрипторы.
После завершения работы клиента и сервера с помощью экземпляра канала сервер должен сначала вызвать функцию FlushFileBuffers, чтобы убедиться, что все байты или сообщения, записанные в канал, считываются клиентом. FlushFileBuffers не возвращается, пока клиент не считывает все данные из канала. Затем сервер вызывает функцию DisconnectNamedPipe, чтобы закрыть подключение к клиенту канала. Эта функция делает дескриптор клиента недопустимым, если он еще не закрыт. Все непрочитанные данные в канале удаляются. После отключения клиента сервер вызывает функцию CloseHandle, чтобы закрыть его дескриптор экземпляра канала. Кроме того, сервер может использовать ConnectNamedPipe для подключения нового клиента к этому экземпляру канала.
Процесс может получить сведения об именованном канале, вызвав функцию GetNamedPipeInfo, которая возвращает тип канала, размер входных и выходных буферов и максимальное количество экземпляров каналов, которые можно создать. Функция GetNamedPipeHandleState в режимах чтения и ожидания дескриптора канала, текущего количества экземпляров канала и дополнительных сведений для каналов, которые взаимодействуют по сети. Функция SetNamedPipeHandleState задает режим чтения и режим ожидания дескриптора канала. Для клиентов канала, взаимодействующих с удаленным сервером, функция также управляет максимальным количеством байтов для сбора или максимального времени ожидания перед передачей сообщения (если дескриптор клиента не был открыт с включенным режимом записи).