Цель работы
Изучение построения клиент-серверного взаимодействия
процессов с использованием почтовых ящиков. Изучение особенностей работы нитей
при использовании ждущих таймеров.
Список используемых системных вызовов
CreateMailslot,
CreateFile,
GetMailslotInfo, SetMailslotInfo, ReadFile, ReadFileEx, WriteFile, WriteFileEx,
CreateWaitableTimer,
OpenWaitableTimer, SetWaitableTimer, TimerAPCProc, CancelWaitableTimer,
SleepEx, WaitForSingleObjectEx,
WaitForMultipleObjectsEx.
Методические указания
Почтовые ящики позволяют процессам обмениваться данными в
пределах локальной сети Microsoft.
Для создания почтового ящика на стороне сервера используется функция CreateMailslot. На стороне клиента используется
функция работы с файлами CreateFile. Для записи и
чтения из почтового ящика используются функции ReadFile и WriteFile
соответственно. (Для работы почтового ящика совместно с ждущим таймером следует
использовать функции ReadFileEx и WriteFileEx). Для получения информации о наличии данных
в почтовом ящике на стороне сервера используется функция GetMailslotInfo.
Следует обратить внимание, что в ОС Windows9X эта функция работает
некорректно и значение параметра lpNextSize необходимо проверять на наличие сообщения следующим способом:
if ((dwNextSize |
0xffff0000) != MAILSLOT_NO_MESSAGE)
{
// Данные есть
}
Ждущие таймеры используются для выполнения определенных
действий в заданное время или через заданный интервал времени. Ждущий таймер
создается с помощью функции CreateWaitableTimer.
Ожидание срабатывания таймера можно производить с помощью WaitFor-функций. Другой способ –
задать специальную callback-функцию,
которая выполнится сразу после перехода таймера в сигнальный режим. При этом
нить должна находится в особом состоянии, называемом «тревожным» (alertable). Нить находится в
этом состоянии при выполнении функций ожидания с суффиксом Ex: ReadFileEx,
WriteFileEx, SleepEx,
WaitForSingleObjectEx, WaitForMultipleObjectsEx, и других.
Ждущие таймеры, как и мьютексы, бывают с ручным сбросом и
синхронизирующие. Синхронизирующие таймеры используются для временной
синхронизации процессов и нитей или для однократного вызова callback-функции. Ждущие таймеры
используются для периодического вызова callback-функции.
С помощью ждущих таймеров можно легко программировать
максимальное время ожидания поступления данных в почтовый ящик.
Задания
11. Разработать
программу, передающую на сервер данные о версии операционной системы (функция GetVersionEx).
Листинг программы.
Первая программа:
#include
<windows.h>
#include
<stdio.h>
#include
<conio.h>
#include
<stdlib.h>
#include
<string.h>
void main()
{
HANDLE hMailSlot;
char chBuffer[256],tmp[256];
DWORD dwBytesRead;
OSVERSIONINFO VerSys; //в данной структуре хранится информация о
версии системы
//присоединяемся
к почтовому ящику
// для
посылки сообщения серверу необходимо испоьзовать следующую строку
// "\\\\Servers\\mailslot\\messngr"
hMailSlot =
CreateFile("\\\\.\\mailslot\\myslot",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hMailSlot==INVALID_HANDLE_VALUE)
{
printf("\n Error
connect to mailslot!!!");
exit(0);
}
//пишем
информацию в почтовый ящик
ZeroMemory(&VerSys, sizeof(OSVERSIONINFO)); //Функция ZeroMemory заполняет указанный фрагмент памяти нулями
//Перед
использованием этой функции надо указать размер структуры
//в
параметре dwOSVersionInfoSize
используя sizeof(OSVERSIONINFO).
VerSys.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
if(GetVersionEx((OSVERSIONINFO*)&VerSys)==false)printf("\n
:((");
//компонуем строку о версии ОС
if(VerSys.dwPlatformId ==
VER_PLATFORM_WIN32_WINDOWS)
{
if(VerSys.dwMinorVersion==0)
strcpy(chBuffer,"Windows
95 Version[");
else
if(VerSys.dwMinorVersion==10)
strcpy(chBuffer,"Windows
98 Version[");
else
if(VerSys.dwMinorVersion==90)
strcpy(chBuffer,"Windows
ME Version[");
}
else if (VerSys.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if(VerSys.dwMajorVersion==3)
strcpy(chBuffer,"Windows
NT 3.51 Version[");
else
if(VerSys.dwMajorVersion==4)
strcpy(chBuffer,"Windows
NT 4.0 Version[");
else
if(VerSys.dwMajorVersion==5)
{
if(VerSys.dwMinorVersion==0)
strcpy(chBuffer,"Windows
2000 Version[");
if(VerSys.dwMinorVersion==1)
strcpy(chBuffer,"Windows
XP Version[");
if(VerSys.dwMinorVersion==2)
strcpy(chBuffer,"Windows
.NET Server Version[");
}
}
itoa(VerSys.dwMajorVersion,tmp,10);
strcat(chBuffer,tmp);
strcat(chBuffer,".");
itoa(VerSys.dwMinorVersion,tmp,10);
strcat(chBuffer,tmp);
strcat(chBuffer,".");
itoa(VerSys.dwBuildNumber,tmp,10);
strcat(chBuffer,tmp);
strcat(chBuffer,"]");
strcat(chBuffer," ");
strcat(chBuffer, VerSys.szCSDVersion);
if (WriteFile(hMailSlot,
&chBuffer, strlen(chBuffer), &dwBytesRead, NULL)!=0)
printf("\n Ok
Write!!!");
getch();
}
Вторая программа:
#include
<windows.h>
#include
<stdio.h>
#include
<conio.h>
void main()
{
HANDLE hMailSlot;
char chBuffer[256];
DWORD dwBytesRead;
//создадим сервер почтового слота
hMailSlot =
CreateMailslot("\\\\.\\mailslot\\myslot",0,
MAILSLOT_WAIT_FOREVER,NULL);
if (hMailSlot==INVALID_HANDLE_VALUE)
{
printf("\n Error
creating mailslot!!!");
exit(0);
}
//прочитаем
информацию из почтового ящика
if (ReadFile(hMailSlot,
&chBuffer, 255, &dwBytesRead, NULL)!=0)
{
chBuffer[dwBytesRead]=NULL;
printf("\n Ok
read: %s",chBuffer);
}
getch();
}
Вывод: изучили построения клиент-серверного
взаимодействия процессов с использованием почтовых ящиков. Изучили особенности
работы нитей при использовании ждущих таймеров.
Комментариев нет:
Отправить комментарий