Поделиться через


Операции с именованным каналом

При первом вызове функции 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 задает режимы чтения и ожидания дескриптора канала. Для клиентов канала, взаимодействующих с удаленным сервером, функция также управляет максимальным количеством собираемых байтов или максимальным временем ожидания перед передачей сообщения (при условии, что дескриптор клиента не был открыт с включенным режимом записи).