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

2.2. Создание клиентского приложения

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

Рис. 2

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

var

Form1: TForm1;

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

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

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

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

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

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

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

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

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

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

OvLap, OvLapClient: TOVERLAPPED; {Структуры OVERLAPPED для

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

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

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

hThreadR, hThreadW, hThreadC: THANDLE; {Описатели

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

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

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

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

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

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

implementation.

3) Напишите дополнительную процедуру для создания нового потока. Функция циклически опрашивает готовность клиента установить соединение.

procedure ThreadConnect;

Var flg: Boolean;

begin

ZeroMemory(@Ovlap, sizeof(TOVERLAPPED));

OvLap.hEvent := Evnt;

While not flg do

Begin

ret := ConnectNamedPipe(PipeClient, @OvLap);

if (ret<>False) or ((ret<>False) and (GetLastError<>ERROR_PIPE_CONNECTED))

then flg := True

else Sleep(1000);

end;

end;.

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

procedure ThreadRead;

begin

ZeroMemory(@Ovlap, sizeof(TOVERLAPPED));

OvLap.hEvent := Evntclient;

ZeroMemory(@buffers, sizeof(buffers));

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

WaitForSingleObject(Evntclient, Infinite);

Form1.Edit2.Text := Buffers;

end;.

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

procedure ThreadWrite;

Var retw: Boolean;

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

begin

ZeroMemory(@OvlapClient, sizeof(TOVERLAPPED));

OvLapClient.hEvent := Evntclient;

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

retw := WriteFile(PipeClient, Bf, sizeof(bf), BytesWritten, @OvLapClient);

WaitForSingleObject(evntclient, INFINITE);

end;.

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

procedure TForm1.FormCreate(Sender: TObject);

begin

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

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

if Evnt=0 then

begin

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

[GetLastError]);

exit; end;

//Создание события на клиенте

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

if Evntclient=0 then

begin

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

[GetLastError]);

exit; end;

end;.

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

procedure TForm1.Button2Click(Sender: TObject);

begin

strcat(@pipe_Name,'\\.\Pipe\Jim');

if WaitNamedPipe(@PIPE_NAME, NMPWAIT_WAIT_FOREVER)=False then

begin

ShowMessageFmt('Функция WaitNamedPipe завершена с ошибкой %d', [GetLastError]);

exit; end;

// Открытие экземпляра именованного канала

PipeClient := CreateFile(@PIPE_NAME, GENERIC_READ or GENERIC_WRITE, 0, Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0);

if PipeClient=INVALID_HANDLE_VALUE then

begin

ShowMessageFmt('Функция CreateFile завершена с ошибкой %d',

[GetLastError]);

end

else ShowMessage('Клиент работает');

end;.

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

procedure TForm1.Button3Click(Sender: TObject);

begin

pFunc3 := @ThreadConnect;

hThreadC := CreateThread(nil,0,pFunc3,nil,0,ThreadID1);

end;.

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

procedure TForm1.Button5Click(Sender: TObject);

begin

pFunc2 := @ThreadWrite;

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

end;.

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

procedure TForm1.Button4Click(Sender: TObject);

begin

pFunc1 := @ThreadRead;

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

end;.

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

procedure TForm1.Button6Click(Sender: TObject);

begin

if DisconnectNamedPipe(Pipeclient)=False then

begin

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

exit; end;

CloseHandle(PipeClient);

CloseHandle(evnt);

end;.

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

procedure TForm1.Button8Click(Sender: TObject);

begin

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

end;.

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

begin

Form1.Close;

end;.

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

15) Проверьте совместную работу клиента и сервера в неблокирующем режиме по передаче пакетов различной длины.

ЛИТЕРАТУРА

Джонс Э., Оланд Дж. Программирование в сетях MicrosoftWindows. Мастер-класс /Пер. с англ. М., Издательско-торговый дом «Русская редакция», 2002. 608 с.

КОНТРОЛЬНЫЕ ВОПРОСЫ

  1. Объясните особенности работы функций файлового ввода-вывода в асинхронном (неблокирующем режиме).

  2. Какие объекты синхронизации вы знаете?

  3. Опишите алгоритм работы многопоточного приложения.

  4. Для каких целей используется функция WaitForSingleObject?

  5. Перечислите преимущества асинхронного (неблокирующего) режима работы.

  6. Какие функции именованных каналов надо настроить на неблокирующий режим?

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