
- •1. Каналы. Именованные и анонимные каналы. Назначение. Области применения
- •2.Использование анонимных каналов
- •3. Использование именованных каналов
- •3.1. Серверная сторона именованных каналов
- •3.2. Клиентская сторона именованных каналов
- •3.3. Решения при разработке сервера именованного канала
- •4. Порядок выполнения работы
- •5.Контрольные вопросы
- •Приложения
- •1.Пример многопоточного сервера
- •2.Пример клиента
- •3.Использование дополнительных функций
- •4.Пример сервера с асинхронным вводом – выводом
- •5.Пример сервера с процедурами завершения
2.Пример клиента
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
HANDLE hPipe;
LPVOID lpvMessage;
CHAR chBuf[512];
BOOL fSuccess;
DWORD cbRead, cbWritten, dwMode;
LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";
// Попытка открыть именованный канал. Ожидание если требуется.
while (1)
{
hPipe = CreateFile(
lpszPipename, // имя канала
GENERIC_READ | // доступ на чтение и запись
GENERIC_WRITE,
0, // не разделяемый ресурс
NULL, // без атрибутов SECURITY
OPEN_EXISTING, // открыть существующий канал
0, // атрибуты по умолчанию
NULL); // не временный файл
// Прервать выполнение цикла, если не получен дескриптор канала
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Выход если произошла ошибка за исключением ERROR_PIPE_BUSY.
if (GetLastError() != ERROR_PIPE_BUSY)
{
printf("Could not open pipe");
exit(1);
}
// Все экземпляры канала заняты - ожидание 20000 милисек
if (! WaitNamedPipe(lpszPipename, 20000) )
printf("Could not open pipe");
}
// Канал соединен. Перевод канала в режим чтения сообщений.
dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(
hPipe, // дескриптор канала
&dwMode, // новый режим канала
NULL, // не устанавливаем макс кол-во байт
NULL); // не устанавливаем макс времмя
if (!fSuccess)
printf("SetNamedPipeHandleState Error");
// Посылаем сообщение серверу канала.
lpvMessage = (argc > 1) ? argv[1] : "default message";
fSuccess = WriteFile(
hPipe, // дескриптор канала
lpvMessage, // указатель на сообщение
strlen((char *)lpvMessage) + 1, // длина сообщения
&cbWritten, // количество записанных байт
NULL); // без not overlapped
if (! fSuccess)
printf("WriteFile Error");
do
{
// Чтение из канала
fSuccess = ReadFile(
hPipe, // дескриптор канала
chBuf, // буфер для получения ответа
512, // размер буфера
&cbRead, // количество байт для чтения
NULL); // not overlapped
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
break;
// Ответ от канала записываем в STDOUT.
if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
chBuf, cbRead, &cbWritten, NULL))
{
break;
}
} while (! fSuccess); // повтор цикал если ERROR_MORE_DATA
CloseHandle(hPipe); // закрытие канала
return 0;
}
3.Использование дополнительных функций
fSuccess = TransactNamedPipe(
hPipe, // дескриптор канала
lpszWrite, // сообщение для сервера
strlen(lpszWrite)+1, // длина сообщения
chReadBuf, // буфер для ответа
512, // размер буфера для ответа
&cbRead, // количество прочитанных байт
NULL); // не асинхронная
// выход если произошла ошибка за исключением ошибки ERROR_MORE_DATA
// считано невсе сообщение
if (!fSuccess && (GetLastError() != ERROR_MORE_DATA))
{
MyErrExit("TransactNamedPipe");
}
while(1)
{
// данные из канала записываем в STDOUT.
if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
chReadBuf, cbRead, &cbWritten, NULL) )
break;
// Break if TransactNamedPipe or ReadFile is successful.
if (fSuccess)
break;
// Чтение из канала если не все прочитали в пред раз.
fSuccess = ReadFile(
hPipe, // дескриптор канала
chReadBuf, // буфер для получения ответа
512, // размер буфера
&cbRead, // количество прочитанных байт
NULL); // не асинхронный ввод / вывод
// Выход по любой ошибке кроме ERROR_MORE_DATA.
if (! fSuccess && (GetLastError() != ERROR_MORE_DATA))
break;
}
// Выполняет операции соединения, ожидания, записи, чтения и закрытия
fSuccess = CallNamedPipe(
lpszPipename, // название канала
lpszWrite, // сообщение серверу
strlen(lpszWrite)+1, // длина сообщения
chReadBuf, // буфер для получения ответа
512, // размер буфера
&cbRead, // количество прочитанных байт
20000); // ожидание 20 секунд
if (fSuccess || GetLastError() == ERROR_MORE_DATA)
{
// Данные из канала STDOUT.
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
chReadBuf, cbRead, &cbWritten, NULL);
// Канал закрыт, не может быть прочитано дополнительная информация из него
if (! fSuccess)
printf("\n...extra data in message was lost\n");