Организация каналов в ОC Windows
Анонимные каналы
Анонимные каналы в Windows - это полудуплексное средство потоковой передачи байтов между родственными процессами. Они функционируют в пределах локальной вычислительной системы и хорошо подходят для перенаправления выходного потока одной программы на вход другой. Анонимные каналы реализованы при помощи именованных каналов с уникальными именами.
Анонимные каналы создаются процессом сервером при помощи функции CreatePipe:
BOOL CreatePipe(
PHANDLE hReadPipe, // описатель для чтения
PHANDLE hWritePipe, // описатель для записи
LPSECURITY_ATTRIBUTES lpPipeAttributes, // атрибуты безопасности
DWORD nSize // размер канала
);
Функция CreatePipe возвращает два описателя (дескриптора) для чтения и записи в канал. После создания канала необходимо передать клиентскому процессу эти дескрипторы (или один из них), что обычно делается с помощью механизма наследования.
Для наследования описателя нужно, чтобы дочерний процесс создавался функцией CreateProcess с флагом наследования TRUE. Предварительно нужно создать наследуемые описатели. Это можно, например, сделать путем явной спецификации параметра bInheritHandle структуры SECURITY_ATTRIBUTES при создании канала.
Другим способом является создание наследуемого дубликата имеющегося описателя при помощи функции DuplicateHandle и последующая передача его создаваемому процессу через командную строку или каким-либо иным образом.
Получив нужный описатель, клиентский процесс, так же как и сервер, может далее взаимодействовать с каналом при помощи функций ReadFile и WriteFile. По окончании работы с каналом оба процесса должны закрыть описатели при помощи функции CloseHandle.
Прогон программы общения процесса через анонимный канал с самим собой
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE hRead, hWrite;
char BufIn[100], *BufOut = "0123456789";
int BufSize = 100;
int BytesOut = 10, BytesIn = 5, i;
if(!CreatePipe(&hRead, &hWrite, NULL, BufSize))
printf("Create pipe failed.\n");
WriteFile(hWrite, BufOut, BytesOut, &BytesOut, NULL);
printf("Write into pipe %d bytes : ", BytesOut);
for(i=0; i<BytesOut;i++) printf("%c",BufOut[i]);
printf("\n");
ReadFile(hRead, BufIn, BytesIn, &BytesIn, NULL);
printf("Read from pipe %d bytes : ", BytesIn);
for(i=0; i<5;i++) printf("%c",BufIn[i]);
return 0;
}
В приведенной программе создается анонимный канал, в него записывается строка цифр, затем часть этой строки читается и выводится на экран.
Прогон программы общения через анонимный канал клиента и сервера
В качестве самостоятельного упражнения рекомендуется организовать через анонимный канал межпроцессное взаимодействие. Процесс-сервер должен создать канал, записать в него информацию и запустить процесс-клиент, задача которого - записанную информацию из канала извлечь.
Именованные каналы
Именованные каналы являются объектами ядра ОС Windows, позволяющими организовать межпроцессный обмен не только в изолированной вычислительной системе, но и в локальной сети. Они обеспечивают дуплексную связь и позволяют использовать как потоковую модель, так и модель, ориентированную на сообщения. Обмен данными может быть синхронным и асинхронным.
Каналы должны иметь уникальные в рамках сети имена в соответствии с правилами именования ресурсов в сетях Windows (Universal Naming Convention, UNC), например, \\ServerName\pipe\PipeName. Для общения внутри одного компьютера имя записывается в форме \\.\pipe\PipeName, где "." обозначает локальную машину. Слово "pipe" в составе имени фиксировано, а PipeName - имя, задаваемое пользователем. Эти имена, подобно именам открытых файлов, не являются именами объектов. Они относятся к пространству имен под управлением драйверов файловых систем именованных каналов ( \Winnt\System32\Drivers\Npfs.sys ), привязанному к специальному объекту устройству \Device\NamedPipe, на которое есть ссылка в каталоге глобальных имен объектов \??\Pipe (эти последние имена "видит" утилита WinObj).
Имена созданных именованных каналов можно перечислить с помощью свободно распространяемой утилиты pipelist с сайта http://www.sysinternals.com. Поскольку имена каналов интегрированы в общую структуру имен объектов, приложения могут открывать именованные каналы с помощью функции CreateFile и взаимодействовать с ними через функции ReadFile и WriteFile.