ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.06.2019

Просмотров: 99

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Лабораторная работа № 5

Студента ИТ 14-1 Красовского Абхая

Технологии обмена данными между процессами: каналы

Вариант №9

Цель: Получить навыки в следующих предметных областях:

  • создание и использование каналов;

  • создание и использование процессов



Индивидуальное задание

Реализовать задание взаимодействия потоков, процессов и канала.

Код сервера:


#include <windows.h>

#include <process.h>

#include <iostream>

#define BUFSIZE 4096


using namespace std;


void ThreadF(LPVOID);


void main()

{

setlocale(LC_ALL, "rus");

bool fConnected;

HANDLE hPipe, hThread;

char *pipename = "\\\\.\\pipe\\MyPipe";


// Мы в цикле создаем экземпляр канала и ожидаем подключение клиента.

// Когда клиент подключится, мы создаем отдельный поток для работы с ним.

cout << "Сервер готов!" << endl;

while (true)

{

hPipe = CreateNamedPipe(pipename, // имя канала

PIPE_ACCESS_DUPLEX, // дуплексный режим (чтения и записи)

PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // запись в виде сообщений // чтение в виде сообщений // блокирующий режим

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

BUFSIZE, // размер выходного буфер

BUFSIZE, // размер входного буфер

0, // тайм-аут

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


if (hPipe == INVALID_HANDLE_VALUE)

cout << ("Ошибка при создании канала", GetLastError()) << endl;


// Ждем подключения клиента

fConnected = ConnectNamedPipe(hPipe, NULL) ? true: (GetLastError() == ERROR_PIPE_CONNECTED);

//(логическое выражение) ? (если выражение истинно) : (если выражение ложно)


if (fConnected)

{

cout << "Получено новое соединение." << endl;

// Создаем поток для клиента

hThread = (HANDLE)_beginthreadex(NULL, 0, (unsigned int(_stdcall*)(void*))ThreadF, (void*)hPipe, 0, NULL); // функция создания потока с возможной проверкой его создания

if (hThread == NULL)

cout << "Ошибка при создании потока клиента" << endl;

else

CloseHandle(hThread);

} else

// Клиент не может подключиться, закрываем канал

CloseHandle(hPipe);

}

}


void ThreadF(LPVOID lpvParam)

{

char StringIn[BUFSIZE];

char StringOut[BUFSIZE];

DWORD BytesRead, ReplyBytes, Written;

BOOL fSuccess;

HANDLE hPipe = (HANDLE) lpvParam;


while (true)

{

// Читаем запрос от клиента

fSuccess = ReadFile(

hPipe, //собственно указатель на файл

StringIn, // указатель на буфер - куда записываем считанные данные

sizeof(StringIn), //объем считываемых данных, не может превышать размер буфера

&BytesRead, //фактический размер считанных данных

NULL); // флаг режима доступа к файлу - NULL(синхронный)


if (! fSuccess || BytesRead == 0)

break;


// Приведем полученную строку к верхнему регистру

for (ReplyBytes = 0; (ReplyBytes < BUFSIZE - 1) && (StringIn[ReplyBytes] != 0); ReplyBytes++)

StringOut[ReplyBytes] = toupper(StringIn[ReplyBytes]);

StringOut[ReplyBytes++] = '\0';


// Пишем ответ в канал

fSuccess = WriteFile(

hPipe,

StringOut, // откуда писать

ReplyBytes, // сколько писать

&Written, // число записанных байт

NULL);


if (! fSuccess || ReplyBytes != Written)

break;

}


// Выполним принудительный сброс буферов на сторону клиента

FlushFileBuffers(hPipe); // очищает буфер для указанного файла и заставляет все буферизированные данные быть записанными в этом файле

DisconnectNamedPipe(hPipe); // отсоединение клиента от сервера

CloseHandle(hPipe);

cout << "Клиент прекращает работу" << endl;

}



Код клиента:

#include <windows.h>

#include <iostream>


#include <conio.h>


#define BUFSIZE 512


using namespace std;


void main()

{

setlocale(LC_ALL, "rus");

char *pipename = "\\\\.\\pipe\\MyPipe";

HANDLE hPipe;

char inputBuffer[BUFSIZE];

char Buf[BUFSIZE];

BOOL fSuccess;

DWORD Mode;

char ch;


// Пробуем открыть именованный канал; ждем экземпляр канала, если необходимо

while (true)

{

hPipe = CreateFile(pipename, // Указатель на имя файла

GENERIC_READ | GENERIC_WRITE, //Параметры доступа

0, //Разделяемый доступ

NULL, //безопасность

OPEN_EXISTING, // Описание

0, // Атрибуты файла

NULL); // Файл шаблона

if (hPipe != INVALID_HANDLE_VALUE) break;


// Все экземпяры канала заняты, ждем

if (!WaitNamedPipe(pipename, NMPWAIT_WAIT_FOREVER))

cout << "Невозможно получить доступ к каналу." << endl;


}

cout << "Поздравляю! Вы подключились серверу." << endl;


// Мы подключились к каналу. Переведем его в режим чтения сообщений

Mode = PIPE_READMODE_MESSAGE; // чтение в виде сообщений

if (!(fSuccess = SetNamedPipeHandleState(hPipe, &Mode, NULL, NULL))) // функция устанавливает режим чтения и режим блокировки указанного имени канала

cout << "SetNamedPipeHandleState failed with error" << endl;



do {

cout << "Введите строку: " << endl;

cin >> inputBuffer;


// Шлем сообщение

if (!(fSuccess = WriteFile(

hPipe, //собственно указатель на файл

inputBuffer, // буфер сообщения

strlen(inputBuffer)+1, // размер сообщения (+1 - закрывающий ноль в строке)

&Mode, // число фактически переданных байт

NULL))) // флаг режима доступа к файлу, NULL(синхронный)

cout << "WriteFile failed with error" << endl;


if (!(fSuccess = ReadFile(

hPipe,

Buf, // буфер куда поместить ответ

BUFSIZE, // размер буфера

&Mode, // число фактически прочитанных байт

NULL))) // флаг режима доступа к файлу, NULL(синхронный)

{

cout << "ReadFile failed with error" << endl;

break;

}


cout << "Ответ сервера: " << Buf << endl;


cout << "Повторить (Y/N)? ";

cin >> ch;

} while ('N' != toupper(ch));


CloseHandle(hPipe);

}


Р езультат:
























Смотрите также файлы