Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
сис прог печать.doc
Скачиваний:
22
Добавлен:
11.12.2018
Размер:
329.22 Кб
Скачать

Задание №3

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

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

Индивидуальное задание: Согласно своему индивидуальному заданию реализовать обмен данными о результатах вызова функций Windows API между двумя приложениями по рассмотренной выше в кратких теоретических сведениях и в учебном проекте технологии.

Отчет по лабораторной работе должен содержать тему и цель работы, ход ее выполнения, листинг разработанных приложений (наиболее существенную его часть), макет пользовательского интерфейса и результаты работы программ. Завершать отчет должен вывод об эффективности применения использованной технологии и ее роли в реализации задач системного программирования.

Решение

Механизм отображение данных в разделяемую область является одним из самых удобных механизмов передачи данных между приложениями. Особенно механизм эффективен когда используется совместно с SendMessage. Клиент сообщает посредством SendMessage о готовности приема данных , на что сервер создает посредством вызова функции CreateMappingFile() и отображения MappingViewOfFile() в разделяемую область. Клиент считывает данные и передает сообщение о том что можно удалить разделяемую память посредством SendMessage.

В данном приложении сервер реализует обмен данными следующим образов. Первым запускается серверное приложение, которое создает разделяемую область в памяти. Клиент записывает в эту область команды для реализации на удаленном сервере. Сервер выполняет команды и выдает результат выполнения команды. Преимуществом использования Отображение в память является передачи практически любых видов данных т.к. в функцию передается тип PVOID.

Номера команд и формат передаваемых данных такой же как и в первом приложенни. Только сервер передает данные посредством отображения в память о результате работы процедуры. Сервер также посылает команду WM_COPYDATA о готовности данных в памяти. Клиент считывает данные с памяти и сервер уничножает данные посредством вызова UnmapViewOfFile();

В данной работе не передается структура SYSTEMTIME, а в сервере считывается текущее время с помощью функции GetLocalTime() и передается FILETIME текущее время.

Программа сервера:

_fastcall TForm5::dataread(TMessage& Msg)

{

FILETIME Ftime;

SYSTEMTIME Stime;

GetLocalTime(&Stime);

MAPPING_STRUCT szClient;

HANDLE hMappingFile;

PVOID pMapping;

pcds = (PCOPYDATASTRUCT)Msg.LParam;

char pDataClient[80];

if(pcds->dwData == 5){

Memo1->Lines->Add("Запрос функции GetCurrentDirectory Клиент ID: "+ IntToStr(Msg.WParam));

GetCurrentDirectory(80,pDataClient);

hMappingFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(pDataClient),"GetCurrentDirectory");

pMapping = MapViewOfFile(hMappingFile,FILE_MAP_ALL_ACCESS,0, 0, 0);

strcpy((PTSTR)pMapping,pDataClient);

szClient.NumberOfFunction = 0;

cds.dwData = 15 ; // function identifier

cds.cbData = sizeof( szClient ); // size of data

cds.lpData = &szClient; // data structure

SendMessage( (HANDLE)Msg.WParam,

WM_COPYDATA,

(WPARAM)(HWND) Form5->Handle,

(LPARAM) (PVOID) &cds );

Memo1->Lines->Add((PTSTR)pMapping);

}

if(pcds->dwData == 20){

Memo1->Lines->Add("Запрос функции SystemTimeToFileTime Клиент ID: "+ IntToStr(Msg.WParam));

hMappingFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(FILETIME),"SystemTimeToFileTime");

pMapping = MapViewOfFile(hMappingFile,FILE_MAP_ALL_ACCESS,0, 0, 0);

SystemTimeToFileTime(&Stime,&Ftime);

szClient.NumberOfFunction = 0;

memcpy(pMapping,&Ftime,sizeof(FILETIME));

cds.dwData = 25 ; // function identifier

cds.cbData = sizeof( szClient ); // size of data

cds.lpData = &szClient; // data structure

SendMessage( (HANDLE)Msg.WParam,

WM_COPYDATA,

(WPARAM)(HWND) Form5->Handle,

(LPARAM) (PVOID) &cds );

Memo1->Lines->Add(((FILETIME *)pMapping)->dwLowDateTime);

Memo1->Lines->Add(((FILETIME *)pMapping)->dwHighDateTime);

}

UnmapViewOfFile(hMappingFile);

}

Программа клиент:

pcds = (PCOPYDATASTRUCT)Msg.LParam;

if(pcds->dwData == 15){

HANDLE hFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"GetCurrentDirectory");

PVOID hMapping = MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS,

0,

0,

sizeof(char [80]));

Edit2->Text = (PTSTR)hMapping;

}

if(pcds->dwData == 25){

HANDLE hFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"SystemTimeToFileTime");

PVOID hMapping = MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS,

0,

0,

sizeof(FILETIME));

Memo1->Lines->Add(((FILETIME *)hMapping)->dwLowDateTime);

Memo1->Lines->Add(((FILETIME *)hMapping)->dwHighDateTime);

}

}

void __fastcall TForm6::Button1Click(TObject *Sender)

{

HANDLE hwDispatch;

typedef struct tagMYREC

{

char s1[80];

DWORD n;

} MYREC;

COPYDATASTRUCT MyCDS;

MYREC MyRec;

HRESULT hResult;

MyRec.n = 0;

MyCDS.dwData = 5;

MyCDS.cbData = sizeof( MyRec );

MyCDS.lpData = &MyRec;

hwDispatch = FindWindow( NULL, "Form5" );

if( hwDispatch != NULL )

SendMessage( hwDispatch,

WM_COPYDATA,

(WPARAM)(HWND) Form6->Handle,

(LPARAM) (LPVOID) &MyCDS );

}

void __fastcall TForm6::Button2Click(TObject *Sender)

{

HANDLE hwDispatch;

typedef struct tagMYREC

{

char s1[80];

DWORD n;

} MYREC;

COPYDATASTRUCT MyCDS;

MYREC MyRec;

HRESULT hResult;

MyCDS.dwData = 20;

MyCDS.cbData = sizeof( MyRec );

MyCDS.lpData = &MyRec;

hwDispatch = FindWindow( NULL, "Form5" );

if( hwDispatch != NULL )

SendMessage( hwDispatch,

WM_COPYDATA,

(WPARAM)(HWND) Form6->Handle,

(LPARAM) (LPVOID) &MyCDS );

else

MessageBox( Form6->Handle, "Can't send WM_COPYDATA", "Клиент", MB_OK );

}

Результат:

Вывод: преимуществом использования отображения является меньшая по сравнению с чтением/записью нагрузка на операционную систему — дело в том, что при использовании отображений операционная система не загружает в память сразу весь файл, а делает это по мере необходимости, блоками размером со страницу памяти (как правило 4 килобайта).