Использование именованных каналов

Сервер создает именованный канал при помощи функции CreateNamedPipe (см. MSDN).

Помимо имени канала в форме, описанной выше, в число параметров функции входят: флаг, указывающий модель передачи данных; параметр, определяющий синхронный или асинхронный режим работы канала, а также указывающий, должен ли канал быть односторонним или двухсторонним. Кроме того, имеется необязательный дескриптор защиты, запрещающий несанкционированный доступ к именованному каналу, и параметр, определяющий максимальное число одновременных соединений по данному каналу.

Повторно вызывая CreateNamedPipe, можно создавать дополнительные экземпляры этого же канала.

После вызова CreateNamedPipe сервер выполняет вызов ConnectNamedPipe и ждет отклика от клиентов, которые соединяются с каналом при помощи функции CreateFile или CallNamedPipe, указывая при вызове имя созданного сервером канала. Легальный клиент получает описатель, представляющий клиентскую сторону именованного канала, и работа серверной функции ConnectNamedPipe на этом завершается.

После того как соединение по именованному каналу установлено, клиент и сервер могут использовать его для чтения и записи данных через Win32-функции ReadFile и WriteFile.

Прогон программы общения двух процессов через именованный канал

В качестве упражнения рекомендуется осуществить прогон программы общения клиента и сервера через именованный канал.

Сервер

#include <stdio.h>

#include <windows.h>

void main()

{

PROCESS_INFORMATION piProcInfo;

STARTUPINFO SI;

char * ClientName = "client.exe";

HANDLE hPipe;

LPTSTR PipeName = TEXT("\\\\.\\pipe\\MyPipe");

char Buff[255];

DWORD iNumBytesToRead = 255, i;

ZeroMemory(&SI, sizeof(STARTUPINFO));

SI.cb = sizeof(STARTUPINFO);

ZeroMemory(&piProcInfo, sizeof(piProcInfo));

hPipe = CreateNamedPipe(

PipeName, // имя канала

PIPE_ACCESS_DUPLEX, // чтение и запись из канала

PIPE_TYPE_MESSAGE | // передача сообщений по каналу

PIPE_READMODE_MESSAGE | // режим чтения сообщений

PIPE_WAIT, // синхронная передача сообщений

PIPE_UNLIMITED_INSTANCES, // число экземпляров канала

4096, // размер выходного буфера

4096, // размер входного буфера

NMPWAIT_USE_DEFAULT_WAIT, // тайм-аут клиента

NULL); // защита по умолчанию

if (hPipe == INVALID_HANDLE_VALUE)

{

printf("CreatePipe failed: error code %d\n", (int)GetLastError());

return;

}

if((CreateProcess(NULL, ClientName, NULL, NULL, FALSE, 0, NULL, NULL, &SI, &piProcInfo))==0)

{

printf("create client process: error code %d\n", (int)GetLastError());

return;

}

if((ConnectNamedPipe(hPipe, NULL))==0)

{

printf("client could not connect\n");

return;

}

ReadFile(hPipe, Buff, iNumBytesToRead, &iNumBytesToRead, NULL);

for(i=0; i<iNumBytesToRead; i++) printf("%c",Buff[i]);

}

Пример 7.1. (html, txt)

Клиент

#include <stdio.h>

#include <windows.h>

void main()

{

HANDLE hPipe;

LPTSTR PipeName = TEXT("\\\\.\\pipe\\MyPipe");

DWORD NumBytesToWrite;

char Buff[] = "Message from Client";

hPipe = CreateFile(

PipeName, // имя канала

GENERIC_READ | // чтение и запись в канал

GENERIC_WRITE,

0, // нет разделяемых операций

NULL, // защита по умолчанию

OPEN_EXISTING, // открытие существующего канала

0, // атрибуты по умолчанию

NULL); // нет дополнительных атрибутов

WriteFile(hPipe, Buff, strlen(Buff), &NumBytesToWrite, NULL);

}

В данном примере сервер создает канал, затем запускает процесс-клиент и ждет соединения. Далее он читает сообщение, посланное клиентом.

Помимо перечисленных выше система представляет еще ряд полезных функций для работы с именованными каналами. Для копирования данных из именованного канала без удаления их из канала используется функция PeekNamedPipe. Функция TransactNamedPipe применяется для объединения операций чтения и записи в канал в одну операцию, которая называется транзакцией. Имеются информационные функции для определения состояния канала, например, GetNamedPipeHandleState или GetNamedPipeInfo. Полный перечень находится в MSDN.

Заключение

Организация совместной деятельности и общения процессов является важной и актуальной задачей. К основным способам межпроцессного обмена традиционно относят каналы и разделяемую память, для организации которых используют разделяемые ресурсы. Анонимные каналы поддерживают потоковую модель, в рамках которой данные представляют собой неструктурированную последовательность байтов. Именованные каналы, поддерживающие как потоковую модель, так и модель, ориентированную на сообщения, обеспечивают обмен данными не только в изолированной вычислительной среде, но и в локальной сети.

Наши рекомендации