Функция CreateNamedPipe
Для создания именованного канала Pipe вы должны использовать функцию CreateNamedPipe. Вот прототип этой функции:
HANDLE CreateNamedPipe(
LPCTSTR lpName, // адрес строки имени канала
DWORD dwOpenMode, // режим открытия канала
DWORD dwPipeMode, // режим работы канала
DWORD nMaxInstances, // максимальное количество
// реализаций канала
DWORD nOutBufferSize, // размер выходного буфера в байтах
DWORD nInBufferSize, // размер входного буфера в байтах
DWORD nDefaultTimeOut, // время ожидания в миллисекундах
LPSECURITY_ATTRIBUTES lpSecurityAttributes); // адрес
// переменной для атрибутов защиты
Через параметр lpName передается адрес строки имени канала в форме \\.\pipe\ИмяКанала (напомним, что при создании канала имя сервера не указывается, так как канал можно создать только на той рабочей станции, где запущен процесс, создающий канал).
Параметр dwOpenMode задает режим, в котором открывается канал. Остановимся на этом параметре подробнее.
Канал Pipe может быть ориентирован либо на передачу потока байт, либо на передачу сообщений. В первом случае данные через канал передаются по байтам, во втором - отдельными блоками заданной длины.
Режим работы канала (ориентированный на передачу байт или сообщений) задается, соответственно, константами PIPE_TYPE_BYTE или PIPE_TYPE_MESSAGE, которые указываются в параметре dwOpenMode. По умолчанию используется режим PIPE_TYPE_BYTE.
Помимо способа передачи данных через канал, с помощью параметра dwOpenMode можно указать, будет ли данный канал использован только для чтения данных, только для записи или одновременно для чтения и записи. Способ использования канала задается указанием одной из следующих констант:
Константа | Использование канала | ||
PIPE_ACCESS_INBOUND | Только для чтения | ||
PIPE_ACCESS_OUTBOUND | Только для записи | ||
PIPE_ACCESS_DUPLEX | Для чтения и записи |
Перечисленные выше параметры должны быть одинаковы для всех реализаций канала (о реализациях канала мы говорили выше). Далее мы перечислим параметры, которые могут отличаться для разных реализаций канала:
Константа | Использование канала | ||
PIPE_READMODE_BYTE | Канал открывается на чтение в режиме последовательной передачи отдельных байт | ||
PIPE_READMODE_MESSAGE | Канал открывается на чтение в режиме передачи отдельных сообщений указанной длины | ||
PIPE_WAIT | Канал будет работать в блокирующем режиме, когда процесс переводится в состояние ожидания до завершения операций в канале | ||
PIPE_NOWAIT | Неблокирующий режим работы канала. Если операция не может быть выполнена немедленно, в неблокирующем режиме функция завершается с ошибкой | ||
FILE_FLAG_OVERLAPPED | Использование асинхронных операций (ввод и вывод с перекрытием). Данный режим позволяет процессу выполнять полезную работу параллельно с проведением операций в канале | ||
FILE_FLAG_WRITE_THROUGH | В этом режиме функции, работающие с каналом, не возвращают управление до тех пор, пока не будет полностью завершена операция на удаленном компьютере. Используется только с каналом, ориентированном на передачу отдельных байт и только в том случае, когда канал создан между процессами, запущенными на различных станциях сети |
Дополнительно к перечисленным выше флагам, через параметр dwOpenMode можно передавать следующие флаги защиты:
Флаг |
Описание |
WRITE_DAC |
Вызывающий процесс должен иметь права доступа на запись к произвольному управляющему списку доступа именованного канала access control list (ACL) |
WRITE_OWNER |
Вызывающий процесс должен иметь права доступа на запись к процессу, владеющему именованным каналом Pipe |
ACCESS_SYSTEM_SECURITY |
Вызывающий процесс должен иметь права доступа на запись к управляющему списку доступа именованного канала access control list (ACL) |
Теперь перейдем к параметру dwPipeMode, определяющему режим работы канала. В этом параметре вы можете указать перечисленные выше константы PIPE_TYPE_BYTE, PIPE_TYPE_MESSAGE, PIPE_READMODE_BYTE, PIPE_READMODE_MESSAGE, PIPE_WAIT и PIPE_NOWAIT. Для всех реализаций канала необходимо указывать один и тот же набор констант.
Параметр nMaxInstances определяет максимальное количество реализаций, которые могут быть созданы для канала. Вы можете указывать здесь значения от 1 до PIPE_UNLIMITED_INSTANCES. В последнем случае максимальное количество реализаций ограничивается только наличием свободных системных ресурсов.
Заметим, что если один серверный процесс использует несколько реализаций канала для связи с несколькими клиенсткими, то общее количество реализаций может быть меньше, чем потенциальное максимальное количество клиентов. Это связано с тем, что клиенты могут использовать реализации по очереди, если только они не пожелают связаться с серверным процессом все одновременно.
Параметры nOutBufferSize и nInBufferSize определяют, соответственно, размер буферов, используемых для записи в канал и чтения из канала. При необходимости система может использовать буферы других, по сравнению с указанными, размеров.
Параметр nDefaultTimeOut определяет время ожидания для реализации канала. Для всех реализаций необходимо указывать одинаковое значение этого параметра.
Через параметр lpPipeAttributes передается адрес переменной, содержащей атрибуты защиты для создаваемого канала. В наших приложениях мы будем указывать этот параметр как NULL. В результате канал будет иметь атрибуты защиты, принятые по умолчанию.
В случае успеха функция CreateNamedPipe возвращает идентификатор созданной реализации канала, который можно использовать в операциях чтения и записи, выполняемых с помощью таких функций, как ReadFile и WriteFile.
При ошибке функция CreateNamedPipe возвращает значение INVALID_HANDLE_VALUE. Код ошибки вы можете уточнить, вызвав функцию GetLastError.