Использование именованных каналов
Сервер создает именованный канал при помощи функции 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.
Заключение
Организация совместной деятельности и общения процессов является важной и актуальной задачей. К основным способам межпроцессного обмена традиционно относят каналы и разделяемую память, для организации которых используют разделяемые ресурсы. Анонимные каналы поддерживают потоковую модель, в рамках которой данные представляют собой неструктурированную последовательность байтов. Именованные каналы, поддерживающие как потоковую модель, так и модель, ориентированную на сообщения, обеспечивают обмен данными не только в изолированной вычислительной среде, но и в локальной сети.