Организация каналов в О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.

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