- •Кафедра кит контрольная работа по дисциплине "Системное программирование"
- •Краматорск 2011 Задание №1
- •Задание №2
- •Задание №3
- •Решение
- •Задание №4 Обмен данными между приложениями с использованием технологии динамического обмена данными с помощью сокетов
- •Решение
- •Задание № 5 Обмен данными между приложениями с использованием технологии динамического обмена данными с помощью именованных каналов
- •Задание №6 Использование технологии сом при разработке приложений в Delphi. Создание и использование внутреннего сервера
Задание №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 килобайта).