Процесс создания сервера заключается в последовательном вызове API-функций:

1.  Создать экземпляр ИК с помощью CreateNamedPipe.

2.  «Слушать» клиентские соединения с помощью ConnectNamedPipe.

3.  Читать и записывать данные в ИК с помощью ReadFile и WriteFile.

4.  Завершить соединение с помощью DisconnectNamedPipe.

5.  Закрыть описатель экземпляра ИК с помощью CloseHandle.

Первая из упомянутых функций определена так.

HANDLE CreateNamedPipe(

LPCTSTR Name, // имя ПЯ

DWORD OpenMode, // направление передачи,

// управление вводом-выводом и безопасность

DWORD PipeMode, // режим операций чтения, записи, ожидания

DWORD MaxInst, // максимальное количество экземпляров канала

DWORD OutSize, // размер выходящего буфера

DWORD InSize, // размер входящего буфера

DWORD TimeOut, // Время ожидания соединения, в мс.

LPSECURITY_ATTRIBUTES Attrib); //атрибуты безопасности

Флаги режимов могут быть следующими: PIPE_ACCESS_DUPLEX
(передача данных в обоих направлениях), PIPE_ACCESS_OUTBOUND (данные передаются от сервера к клиенту) и PIPE_ACCESS_INBOUND (от клиента к серверу), FILE_FLAG_WRITE_THROUGH (функции записи не возвращают значение, пока данные передаются по сети или находятся в буфере), FILE_FLAG_OVERLAPPED (используется перекрытый ввод-вывод), WRITE_DAC (можно изменять список избирательного управления доступом), ACCESS_SYSTEM_SECURITY (можно изменять системный список управления доступом), WRITE_OWNER (можно изменять владельца ИК и групповой идентификатор безопасности).

НЕ нашли? Не то? Что вы ищете?

Параметр PipeMode определяет режимы чтения, записи и ожидания. При создании нужно указать по одному флагу из каждой категории, объединив их операцией «|». Для записи данных флаг PIPE_TYPE_BYTE означает, что данные записываются в ИК потоком байтов, PIPE_TYPE_MESSAGE – потоком сообщений. Для чтения PIPE_READMODE_BYTE означает чтение данных потоком байтов, а PIPE_READMODE_MESSAGE – потоком сообщений. Для операции ожидания PIPE_WAIT включает режим блокировки, PIPE_NOWAIT – отключает режим блокировки.

Когда функция CreateNamedPipe вернет описатель ИК, сервер начинает ожидать соединения клиентов. Для установления соединения надо вызвать функцию

BOOL ConnectNamedPipe(

HANDLE Pipe, // описатель ИК

LPOVERLAPPED Overlap); // асинхронное чтение данных из буфера

Сервер именованных конвейеров может выглядеть следующим образом.

#include <windows. h>

#include <stdio. h>

void main(void)

{

HANDLE NPipe;

char buffer[256];

DWORD NumberOfBytesRead;

// Создание ИК

if ((NPipe = CreateNamedPipe("\\\\.\\Pipe\\pipe1",

PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE |

PIPE_READMODE_BYTE, 1, 0, 0, 2000, NULL)) ==

INVALID_HANDLE_VALUE)

{

printf("Ошибка при создании конвейера %d\n",

GetLastError());

return; }

printf (“Сервер запущен.\n”);

if (ConnectNamedPipe(NPipe, NULL) == 0)

{

printf("Ошибка при установлении соединения %d\n",

GetLastError());

CloseHandle (NPipe);

return;

}

if (ReadFile (NPipe, buffer, sizeof (buffer),

&NumberOfBytesRead, NULL) <= 0)

{

printf("Ошибка при чтении из конвейера %d\n",

GetLastError());

CloseHandle (NPipe);

return;

}

printf (“%s\n”, buffer);

if (DisconnectNamedPipe(NPipe) == 0)

{

printf("Ошибка при разрыве соединения %d\n",

GetLastError());

return;

}

CloseHandle (NPipe);

}

Для реализации клиента нужно разработать приложение, которое может подключаться к существующему ИК. В таком приложении необходимо выполнить следующие шаги:

1.  Для проверки наличия свободного экземпляра ИК нужно вызвать функцию WaitNamedPipe.

2.  Для установления соединения нужно использовать CreateFile.

3.  Читать и записывать данные в ИК с помощью ReadFile и WriteFile.

4.  Завершить соединение с помощью функции CloseHandle.

Перед установлением соединения клиент должен проверить наличие свободного ИК с помощью функции

BOOL WaitNamedPipe (

LPCTSTR Name, // имя ИК

DWORD TimeOut); // величина ожидания свободного ИК

Затем клиент может открыть этот экземпляр ИК с помощью CreateFile, указав в качестве имени название открываемого ИК. Поскольку клиент
может при желании читать и/или записывать данные на сервер, то параметр DesAccess может быть GENERIC_WRITE либо GENERIC_READ либо GENERIC_WRITE | GENERIC_READ. Параметр Sharing должен быть только 0, поскольку только один клиент получает доступ к ИК. Флаг CreateDispos обязан быть OPEN_EXISTING, а Flags должен обязательно включать FILE_ATTRIBUTE_NORMAL.

Пример клиента именованного конвейера приведен ниже.

#include <windows. h>

#include <stdio. h>

void main(void)

{

HANDLE NPipe;

DWORD BytesWritten;

if (WaitNamedPipe("\\\\.\\Pipe\\pipe1",

NMPWAIT_WAIT_FOREVER) == 0)

{

printf("Ожидание соединения с ошибкой %d\n",

GetLastError());

return;

}

// создание описателя ИК

if ((NPipe = CreateFile("\\\\.\\Pipe\\pipe1", GENERIC_READ |

GENERIC_WRITE, 0, (LPSECURITY_ATTRIBUTES)NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,

(HANDLE)NULL)) == INVALID_HANDLE_VALUE)

{

printf("Создание файла с ошибкой %d\n",

GetLastError());

return;

}

if (WriteFile (NPipe, “Test string”,

strlen (“Test string”),

&BytesWritten, NULL) == 0)

{

printf("Запись в файл с ошибкой %d\n", GetLastError());

CloseHandle (NPipe);

return;

}

printf("Записано %d байтов\n", BytesWritten);

CloseHandle(NPipe);

}

Варианты заданий к лабораторной работе №8

Вариант №1

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик два числа L и U, введенные пользователем, где L – это нижняя граница диапазона, U – верхняя граница диапазона. Сервер принимает значения границ диапазона из почтового ящика, вычисляет сумму и произведение чисел от L до U и выводит полученные значения на экран.

Вариант №2

Разработать две программы – сервер и клиент. Клиент отсылает серверу введенный пользователем номер числа Фибоначчи через именованный конвейер. Сервер принимает из именованного конвейера номер, вычисляет число Фибоначчи с этим номером, по формуле Fi = Fi–1 + Fi–2, F0 = F1 = 1 и выводит его на экран.

Вариант №3

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик введенную пользователем строку, хранящую знаковое целое число. Сервер принимает из почтового ящика строку, хранящую знаковое целое число, и выводит на экран строковый эквивалент этого числа прописью (например, ввод «-1211» должен приводить к выводу «минус тысяча двести одиннадцать»).

Вариант №4

Разработать две программы – сервер и клиент. Клиент отсылает серверу через именованный конвейер введенную пользователем строку, хранящую число со знаком и плавающей точкой. Сервер принимает из именованного конвейера строку, хранящую число со знаком и плавающей точкой, и выводит на экран строковый эквивалент этого числа прописью (например, ввод «-12.11» должен приводить к выводу «минус двенадцать целых одиннадцать сотых»).

Вариант №5

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик две строки, введенные пользователем. Сервер принимает из почтового ящика две строки. Далее, если обе строки хранят целые числа со знаком, то на экран выводится сумма чисел, в противном случае – конкатенация двух введенных строк.

Вариант №6

Разработать две программы – сервер и клиент. Клиент отсылает серверу через именованный конвейер элементы двух прямоугольных матриц, введенные пользователем. Сервер принимает из именованного конвейера две прямоугольных матрицы, а затем выводит на экран их сумму и произведение.

Вариант №7

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик элементы вектора (одномерного целочисленного массива), введенные пользователем. Сервер принимает вектор из почтового ящика, упорядочивает его по возрастанию любым из так называемых «улучшенных алгоритмов» сортировки массивов и выводит на экран.

Вариант №8

Разработать две программы – сервер и клиент. Клиент отсылает серверу через именованный конвейер элементы вектора (одномерного массива чисел с плавающей точкой), введенные пользователем. Сервер принимает вектор из именованного конвейера, упорядочивает его по возрастанию любым из так называемых «улучшенных алгоритмов» сортировки массивов и выводит на экран.

Вариант №9

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик элементы вектора (одномерного массива строк), введенные пользователем. Сервер принимает вектор из почтового ящика, упорядочивает его по возрастанию любым из так называемых «улучшенных алгоритмов» сортировки массивов и выводит на экран.

Вариант №10

Разработать две программы – сервер и клиент. Клиент отсылает серверу через именованный конвейер элементы введенной пользователем квадратной матрицы. Сервер принимает матрицу из именованного конвейера, затем вычисляет сумму элементов, лежащих на главной и побочной диагоналях, и выводит на экран.

Вариант №11

Разработать две программы – сервер и клиент. Клиент отсылает серверу через почтовый ящик элементы введенной пользователем квадратной матрицы. Сервер принимает матрицу из почтового ящика, затем вычисляет сумму элементов, не лежащих на главной и побочной диагоналях, и выводит на экран.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26