Установка соединения с каналом со стороны сервера
После того как серверный процесс создал канал, он может перейти в режим соединения с клиентским процессом. Соединение со стороны сервера выполняется с помощью функции ConnectNamedPipe.
Прототип функции ConnectNamedPipe представлен ниже:
BOOL ConnectNamedPipe(
HANDLE hNamedPipe, // идентификатор именованного канала
LPOVERLAPPED lpOverlapped); // адрес структуры OVERLAPPED
Через первый параметр серверный процесс передает этой функции идентификатор канала, полученный от функции CreateNamedPipe.
Второй параметр используется только для огранизации асинхронного обмена данными через канал. Если вы используете только синхронные операции, в качестве значения для этого параметра можно указать NULL.
В случае успеха функция ConnectNamedPipe возвращает значение TRUE, а при ошибке - FALSE. Код ошибки можно получить с помощью функции GelLastError.
В зависимости от различных условий функция ConnectNamedPipe может вести себя по разному.
Если параметр lpOverlapped указан как NULL, функция выполняется в синхронном режиме. В противном случае используется асинхронный режим.
Для канала, созданного в синхронном блокирующем режиме (с использованием константы PIPE_WAIT), функция ConnectNamedPipe переходит в состояние ожидания соединения с клиентским процессом. Именно этот режим мы будем использовать в наших примерах программ, исходные тексты которых вы найдете ниже.
Если канал создан в синхронном неблокирующем режиме, функция ConnectNamedPipe немедленно возвращает управление с кодом TRUE, если только клиент был отключен от данной реализации канала и возможно подключение этого клиента. В противном случае возвращается значение FALSE. Дальнейший анализ необходимо выполнять с помощью функции GetLastError. Эта функция может вернуть значение ERROR_PIPE_LISTENING (если к серверу еще не подключен ни один клиент), ERROR_PIPE_CONNECTED (если клиент уже подключен) или ERROR_NO_DATA (если предыдущий клиент отключился от сервера, но клиент еще не завершил соединение).
Ниже мы привели пример использования функции ConnectNamedPipe:
HANDLE hNamedPipe;
LPSTR lpszPipeName = "\\\\.\\pipe\\$MyPipe$";
hNamedPipe = CreateNamedPipe(
lpszPipeName,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
512, 512, 5000, NULL);
fConnected = ConnectNamedPipe(hNamedPipe, NULL);
В данном случае функция ConnectNamedPipe перейдет в состояние ожидания, так как канал был создан для работы в синхронном блокирующем режиме.