Академический Документы
Профессиональный Документы
Культура Документы
Анонимные каналы
Именованные каналы
Однонаправленная передача данных между процессами с
использованием именованного канала
Рассмотрим использование описанных выше средств Win32
API для организации передачи данных от сервера к клиенту
на одном компьютере. Для этого, при создании канала
сервером с помощью функции CreateNamedPipe(),
параметру dwOpenMode задается значение
PIPE_ACCESS_OUTBOUND. Также, при открытии канала
клиентом с помощью функции CreateFile() параметру
dwDesiredAccess задается значение GENERIC_READ.
Приложение – сервер канала должно содержать
следующий код:
…
// Адрес блока передаваемых данных
PVOID lpSendData;
// Размер блока данных и кол-во запис. байтов
DWORD dwSize, dwWritten;
…// Выделение памяти и заполнение блока данными
HANDLE hNamedPipe; // Дескриптор канала
// Создание именованного канала
hNamedPipe = CreateNamedPipe("\\\\.\\pipe\\MyPipe",
PIPE_ACCESS_OUTBOUND, 0, 1, 0, 0,
NMPWAIT_WAIT_FOREVER, NULL);
// Ожидание подключения клиента к каналу
ConnectNamedPipe (hNamedPipe, NULL);
// Запись данных в канал
WriteFile (hNamedPipe, lpSendData, dwSize, &dwWritten,
NULL);
// Отключение соединения с клиентом
DisconnectNamedPipe(hNamedPipe);
// Закрытие дескриптора канала
CloseHandle(hNamedPipe);
…
Приложение – клиент канала должно содержать следующий
код:
…
// Адрес блока получаемых данных
PVOID lpReceiveData;
// Размер блока данных и кол-во прочит. байтов
DWORD dwSize, dwRead;
…// Выделение памяти для блока данных
HANDLE hNamedPipe; // Дескриптор канала
// Ожидание освобождения канала
WaitNamedPipe("\\\\.\\pipe\\MyPipe",
NMPWAIT_WAIT_FOREVER);
// Подключение клиента к каналу
hNamedPipe = CreateFile("\\\\.\\pipe\\MyPipe",
GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
// Чтение данных из канала
ReadFile(hNamedPipe, lpReceiveData, dwSize, &dwRead,
NULL);
// Закрытие дескриптора канала
CloseHandle(hNamedPipe);
…
Примечание. Для организации передачи данных от клиента
к серверу необходимо: - при создании канала сервером с
помощью функции CreateNamedPipe() параметру
dwOpenMode задать значение PIPE_ACCESS_INBOUND; -
при открытии канала клиентом с помощью функции
CreateFile() параметрe dwDesiredAccess задать значение
GENERIC_WRITE.
Двухсторонняя передача данных между процессами с
использованием именованного канала
Для организации дуплексной передачи данных между
сервером и клиентом необходимо: - при создании канала
сервером с помощью функции CreateNamedPipe()
параметру dwOpenMode задать значение
PIPE_ACCESS_DUPLEX; - при открытии канала клиентом с
помощью функции CreateFile() параметру dwDesiredAccess
задать значение GENERIC_ READ | GENERIC_ WRITE.
Приложение – сервер канала должно содержать
следующий код:
…
// Адрес блока данных для запроса и ответа
PVOID lpRequest, lpResponse;
DWORD dwSize1, dwSize2; // Размеры блоков данных
// Кол-во прочитанных и записанных байтов
DWORD dwRead, dwWritten;
… // Выделение памяти для блоков данных
HANDLE hNamedPipe; // Дескриптор канала
// Создание именованного канала
hNamedPipe = CreateNamedPipe("\\\\.\\pipe\\MyPipe",
PIPE_ACCESS_DUPLEX, 0, 1, 0, 0,
NMPWAIT_WAIT_FOREVER, NULL);
// Ожидание подключения клиента к каналу
ConnectNamedPipe (hNamedPipe, NULL);
// Чтение в цикле запросов от клиента
while (ReadFile(hNamedPipe, lpRequest, dwSize1, &dwRead,
NULL))
{
… // Обработка очередного запроса
// Запись ответа в канал
WriteFile (hNamedPipe, lpResponse, dwSize2, &dwWritten,
NULL);
}
// Отключение соединения с клиентом
DisconnectNamedPipe(hNamedPipe);
// Закрытие дескриптора канала
CloseHandle(hNamedPipe);
…
Приложение – клиент канала должно содержать следующий
код:
…
// Адрес блока данных для запроса и ответа
PVOID lpRequest, lpResponse;
DWORD dwSize1, dwSize2; // Размеры блоков данных
// Кол-во прочитанных и записанных байтов
DWORD dwRead, dwWritten;
INT nReqCount; // Количество запросов к серверу
… // Выделение памяти для блоков данных
HANDLE hNamedPipe; // Дескриптор канала
// Ожидание освобождения канала
WaitNamedPipe("\\\\.\\pipe\\MyPipe",
NMPWAIT_WAIT_FOREVER);
// Подключение клиента к каналу
hNamedPipe = CreateFile("\\\\.\\pipe\\MyPipe", GENERIC_
READ | GENERIC_ WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
// Обмен с каналом, пока есть запросы
for (int i=0; i< nReqCount; i++)
{
… // Формирование очередного запроса
// Запись запроса в канал
WriteFile (hNamedPipe, lpRequest, dwSize1, &dwWritten,
NULL);
// Чтение ответа из канала
ReadFile(hNamedPipe, lpResponse, dwSize2, &dwRead,
NULL);
}
// Закрытие дескриптора канала
CloseHandle(hNamedPipe);
…
Таким образом, приведенные фрагменты исходного кода
показывают, как производится дуплексная передача
запросов и ответов между клиентом и сервером
именованного канала. Если сервер и клиент расположены
на разных компьютерах в сети, то в коде клиента при
вызове функции CreateFile() в имени канала необходимо
указывать сетевое имя компьютера сервера.
Дополнительные материалы
Использование почтовых ячеек для передачи данных
между процессами