Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
prakt-Storozhok.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
7.98 Mб
Скачать

1. Теоретическое введение

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

1.1. Особенности организации работы именованных

каналов в неблокирующем режиме

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

  1. в функции CreateNamedPipe указать флаг работы в неблокирующем режиме FILE_FLAG_OVERLAPPED;

  2. в функциях ConnectNamedPipe, ReadFile и WriteFile необходимо передавать, в качестве одного из параметров, адрес инициализированной структуры OVERLAPPED (перекрывающий). Этот параметр указывает, что операции файлового ввода-вывода будут перекрываться с выполнением других операций;

  3. структура OVERLAPPED имеет следующий вид:

OVERLAPPED = record

Internal: DWORD;

InternalHigh: DWORD;

Offset: DWORD;

OffsetHigh: DWORD;

hEvent: THandle;

end;.

В этой задаче структуру OVERLAPPED следует заполнить нулями и инициализировать только одно поле hEvent, в которое записывается описатель объекта синхронизации. Объект синхронизации указывает момент окончания операции.

4) Для асинхронной работы функций ConnectNamedPipe, ReadFile и WriteFile создаются три дополнительных потока. Эти потоки запускают на выполнение соответствующую функцию файлового ввода-вывода (ConnectNamedPipe, ReadFile и WriteFile) и с помощью функции WaitForSingleObject ожидают завершения данных функций.

2. Задание по практическому занятию

Разработать клиент-серверное приложение, выполняющее прием и передачу сообщений от клиента к серверу и от сервера к клиенту в неблокирующем режиме.

2.1. Создание серверного приложения

1) Создать новый проект и разместить на нем элементы управления, как показано на рис. 1.

Рис. 1

2) В раздел VAR проекта ввести следующие переменные:

var

Form1: TForm1;

PipeHandle: THANDLE; {Описатель сервера именованных каналов}

evntserver: THANDLE;{Объект «событие» для организации работы

функции ReadFile и WriteFile в неблокирующем режиме}

BytesRead: DWORD; {Переменная для хранения количества

переданных серверу байт}

buffers: Array [0..80] of char; {Буфер, в который записываются

прочитанные сервером сообщения}

Pipe_name: Array [0..80] of char {Буфер для хранения имени канала};

OvLap: TOVERLAPPED; {Структура OVERLAPPED для

работы сервера в неблокирующем режиме}

ret: Boolean; {В эту переменную записывается результат операции}

BytesWritten: DWORD;{Количество передаваемых байт}

hThreadR, hThreadW: THANDLE; {Описатели дополнительных

программных потоков для чтения и записи в неблокирующем режиме}

pFunc1, pFunc2: pointer; {Указатели функций, на основе

которых создаются вспомогательные потоки}

ThreadID1, ThreadID2: CARDINAL; {Идентификаторы

вспомогательных потоков}

implementation.

3) Напишите дополнительную процедуру для создания нового потока. Процедура позволяет читать данные в неблокирующем режиме.

procedure ThreadRead;

begin

ZeroMemory(@Ovlap, sizeof(TOVERLAPPED));

OvLap.hEvent := Evntserver;

ZeroMemory(@buffers, sizeof(buffers));

ret := ReadFile(PipeHandle, buffers, sizeof(buffers), BytesRead, @OvLap);

WaitForSingleObject(Evntserver,Infinite); Form1.Edit2.Text := Buffers;

end;.

4) Напишите дополнительную процедуру для создания нового потока. Процедура позволяет передавать данные клиенту в неблокирующем режиме.

procedure ThreadWrite;

Var retw: Boolean;

Bf: Array [0..80] of Char;

begin

ZeroMemory(@Ovlap, sizeof(TOVERLAPPED));

OvLap.hEvent := Evntserver;

StrCopy(@Bf, PChar(Form1.Edit1.Text));

retw := WriteFile(PipeHandle, Bf, sizeof(bf), BytesWritten, @OvLap);

WaitForSingleObject(evntserver,INFINITE);

end;.

5) Для создаваемой формы в событие OnCreate запишите следующий программный код:

procedure TForm1.FormCreate(Sender: TObject);

begin

//Создание события на сервере

Evntserver := CreateEvent(Nil, FALSE, FALSE, Nil);

if EvntServer=0 then

begin

ShowMessageFmt('Ошибка %d при создании объекта событие',

[GetLastError]);.

CloseHandle(PipeHandle);

exit; end;

end;.

6) Для события OnClick кнопки «Запустить сервер» запишите следующий программный код:

procedure TForm1.Button1Click(Sender: TObject);

begin

// Создание именованного канала

PipeHandle := CreateNamedPipe('\\.\Pipe\Jim', PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED,

PIPE_TYPE_BYTE or PIPE_READMODE_BYTE, 1, 0, 0, 1000, Nil);

if PipeHandle=INVALID_HANDLE_VALUE then

begin

ShowMessageFmt('Ошибка %d при создании именованного канала',

[GetLastError]);

exit; end;

ShowMessage('Сервер работает. Создайте клиента');

end;.

7) Для события OnClick кнопки «Чтение сообщения» запишите следующий программный код:

procedure TForm1.Button4Click(Sender: TObject);

begin

pFunc1 := @ThreadRead;

hThreadR := CreateThread(nil, 0, pFunc1, nil, 0, ThreadID1);

end;.

8) Для события OnClick кнопки «Передача сообщения» запишите следующий программный код:

procedure TForm1.Button5Click(Sender: TObject);

begin

pFunc2 := @ThreadWrite;

hThreadW := CreateThread(nil, 0, pFunc2, nil, 0, ThreadID2);

end;.

9) Для события OnClick кнопки «Закрыть канал» запишите следующий программный код:

procedure TForm1.Button6Click(Sender: TObject);

begin

if DisconnectNamedPipe(PipeHandle) = False then

begin

ShowMessageFmt('Ошибка %d при закрытии канала', [GetLastError]);

end;

CloseHandle(PipeHandle);

end;.

10) Для события OnClick кнопки «Проверка неблокирующего режима» запишите следующий программный код:

procedure TForm1.Button8Click(Sender: TObject);

begin

ShowMessage('Работа в неблокирующем режиме');

end;.

11) Для события OnClick кнопки «Выход» запишите следующий программный код:

procedure TForm1.Button7Click(Sender: TObject);

begin

Form1.Close;

end;.

12) Откомпилируйте проект.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]