Исходный текст
|
Описание
|
1
|
2
|
TCHAR Buf
[1024];
|
Буфер для
данных
|
static HWND
hwndEdit;
|
Дескриптор поля
редактирования текста
|
1
|
2
|
#define
MAX_LOADSTRING 100
|
Строка
заголовка
|
#define
BUF_SIZE 1024
|
Размерность
буфера
|
struct D
|
Структура для
буфера
|
HANDLE hThreads
[2]
|
Дескриптор
потока
|
HANDLE hMapFile
|
Дескриптор отображения
файла
|
HANDLE
hEventVvod
|
Дескриптор
события "Данные готовы"
|
TCHAR
szWindowClass [MAX_LOADSTRING]
|
Имя класса
главного окна
|
HINSTANCE hInst
|
Текущий
экземпляр
|
Оконная процедура программы-сервера. В начале выполняется
анализ кода сообщения (блок 2, рис. 2.3.1 и оператор 120 приложения А). В
зависимости от кода выполняются инструкции, отображенные блоками 3 или 4 (рис.
2.3.1).
При обработке сообщения WM_CREATE в начале блоком 3
выполняется создание отображение объекта (операторы 122-128 приложения А).
Далее выполняется представление проецированного файла (блок 11, рис. 2.3.1 и
операторы 135-137 приложения А). Затем блоком 14 (рис. 2.3.1) выполняется
создание мьютекса (реализовано операторами 144-145 приложения А). С помощью
блока 18 (рис. 2.3.1) выполняется создание окна приложения-сервера с полем
ввода, редактирования и отображения текста (операторы 148-151 приложения А).
Задаются необходимые параметры размеров и расположения на экране окна
приложения-сервера. Далее блоком 19 (рис. 2.3.1) выполняется создание потока
для получения сообщения от приложения-клиента (оператор 153 приложения А).
Рисунок 2.3.1 - Схема алгоритма оконной процедуры
программы-сервера
Для отладки программ необходимо размещать и серверную, и
клиентскую программы на одном локальном компьютере. Это объясняется тем, что
используемый метод отображения файла в память применяется на одном локальном
компьютере.
Результаты
работы приложений
Разработка и отладка программы выполнялась в среде Microsoft
Visual Studio. В итоге было разработано одно приложение-сервер и два приложения
клиента, которые были проверены на практике и выполняют необходимые требования.
В результате выполнения программы от клиентов 1 и 2 по выбору пользователя
передаются данные серверу. Первый клиент передает данные о ширине полосы меню и
о наличии мыши в системе. Второй клинт передеает данные о размерах кнопки
полосы прокрутки и иконки приложения. Сервер получает данные в виде:
"Клиент #1. Сообщение" и "Клиент #2. Сообщение". Также
реализована возможность ввода информации в поле клиентов и отправка ее серверу
вместе с данными. Изображения окон работающих приложений приведены на рисунках
2.4.1 и 2.4.2:
Рис. 2.4.1 - Окна приложений сервера и клиента №1
Рис. 2.4.2 - Окна приложений сервера и клиента №2
Выводы
Целью данной курсовой работы была разработка приложений
архитектуры "клиент-сервер". Разработанные приложения включают:
приложение, выполняющее функции сервера и два приложения, которые выполняют
функции клиентов.
Архитектура "клиент-сервер" позволяет реализовать
обмен информации между двумя устройствами: сервером и клиентом. Согласно данной
технологии, клиент запрашивает у сервера некоторые услуги, предоставляя
определенные исходные данные и параметры с помощью одного из методов
коммуникации между потоками, а сервер обслуживает запрос. Метод коммуникации
между процессами, использованный в данной работе, - отображение файла в память.
В результате выполнения данной курсовой работы было
разработано три приложения: два приложения-клиента, которые получают
необходимую информацию о характеристиках системы и приложение-сервер, которому
полученная информация передается для последующего ее вывода на экран. Были
выполнены требования, представленные к разрабатываемым приложениям.
По окончанию выполнения работы, разработанные приложения были
проверены на практике и полностью подтвердили свою работоспособность. Были
проведены необходимые исследования и составлены схемы алгоритмов к основным
модулям приложений.
Можно сделать вывод, что поставленная задача была достигнута,
задание на курсовой проект было выполнено.
Перечень
ссылок
1. Гордеев
А.В., Молчанов А.Ю. Системное программное обеспечение: Учебник для вузов - СПб:
Питер, 2003. - 736 с. - С.389.
2. Дейтел
Х.М., Дейтел П. Дж., Чофнес Д.Р. Операционные системы. Основы и принципы:
Третье издание. Пер. с англ. - М.: ООО "Бином-Пресс", 2006. - 1024 с.
- С.768.
. Демройк
М.Ю. Начала программирования. Распределенные системы, безопасность схем
программирования. - М.: ООО "Бином-Пресс", 2009. - 704 с. - С.143.
. Джонсон
М. Системное программирование в среде Win32, 2-е изд.: Пер. с англ. - M.:
Издательский дом "Вильямс”, 2001. - 464 с. - С.346.
. Документация
Win32 API (MSDN).
6. Питер Блюм, LabVIEW.
Стиль программирования <http://www.ozon.ru/context/detail/id/4159157/>,
М: "ДМК Пресс <http://www.ozon.ru/context/detail/id/858448/>",
2008.
. Рихтер Дж. Windows
для профессионалов: создание эффективных Win32 приложений с учетом специфики
64-разрядной версии Windows, 4-е изд.: Пер, англ - СПб: Питер; М.:
Издательско-торговый дом "Русская Редакция", 2001. - 752 с. - С.578.
. Страуструп Б. Язык
программирования С++. Специальное издание. Пер. с англ. - М.: ООО "И.Д.
Вильямс", 2007. - 1104 с.
. Суранов А.Я.,
LabVIEW 8.20., Справочник по функциям <http://www.ozon.ru/context/detail/id/3402455/>,
М: "ДМК Пресс <http://www.ozon.ru/context/detail/id/858448/>",
2007.
. Таненбаум Э.
Современные операционные системы, 2-е изд.: Пер. с англ. - СПб: Питер, 2003. -
1040 с. - С.552.
. Таненбаум Э.
Современные операционные системы, 2-е изд.: Пер. с англ. - СПб: Питер, 2003. -
1040 с.
. Трахтенгерц Э.А.
Программное обеспечение параллельных процессов. - М.: Наука, 2003. - 272 с. -
С.84.
. Трэвис Дж., Кринг
Дж., ДМК Пресс", 2008.
. Щербаков Є.В.,
Щербакова М. Є. Мовні засоби системного програмування: навчальний посібник. -
Луганськ: Вид-во СНУ ім.В. Даля, 2006. - 376 с.
. Щербаков Є.В.,
Щербакова М. Є., Скарга-Бандурова І.С. Діалогові засоби системного
програмування: навчальний посібник. - Луганськ: Вид-во СНУ ім.В. Даля, 2010. -
408 с.
. Эндрюс Грегори Р.
Основы многопоточного, параллельного и распределенного программирования. / Пер.
с англ. К.: Диалектика, 2008. - 512 с. - С.153.
. Методические
указания к курсовой работе по дисциплине "Системное программное
обеспечение - 42 с.
. http://loi.
sscc.ru/gis/oop/win32api/win32.html
<http://loi.sscc.ru/gis/oop/win32api/win32.html>
. http://msdn.
microsoft.com/ru-ru/library/bb384843. aspx
<http://msdn.microsoft.com/ru-ru/library/bb384843.aspx>
. http://w32api.
narod.ru/functions/GetSystemMetrics.html
<http://w32api.narod.ru/functions/GetSystemMetrics.html>
Приложения
Приложение А
Распечатка программы-сервера
// MapServer. cpp: определяет точку входа для приложения.
#include "stdafx. h"
#include "MapServer. h"
#include <stdio. h>
#include <process. h>
#include <wchar. h>
#include <sstream>
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024nameMutex =
"Global\\MapMutex";nameEvent =
"Global\\MapEvent";hServerMutex; // дескриптор мьютекса на доступ к
буферу памятиhEventVvod;uThreadIDs [2];hThreads [2];Working=true;hMapFile;HWND
hwndEdit;D{Buf [1024];
};* lpD;
// Глобальные переменные:hInst; // текущий экземплярszTitle
[MAX_LOADSTRING]; // Текст строки заголовкаszWindowClass [MAX_LOADSTRING]; //
имя класса главного окна
// Отправить объявления функций, включенных в этот модуль
кода:(HINSTANCE hInstance);(HINSTANCE, int);CALLBACKWndProc (HWND, UINT,
WPARAM, LPARAM);_PTR CALLBACKAbout (HWND, UINT, WPARAM, LPARAM);APIENTRY
_tWinMain (HINSTANCE hInstance,hPrevInstance,lpCmdLine,nCmdShow)
{UNREFERENCED_PARAMETER (hPrevInstance);_PARAMETER
(lpCmdLine);
// TODO: разместите код здесь.msg;hAccelTable;
// Инициализация глобальных строк(hInstance, IDS_APP_TITLE,
szTitle, MAX_LOADSTRING);(hInstance, IDC_MAPSERVER, szWindowClass,
MAX_LOADSTRING);(hInstance);
// Выполнить инициализацию приложения:(! InitInstance
(hInstance, nCmdShow))
{return FALSE;
}= LoadAccelerators (hInstance, MAKEINTRESOURCE
(IDC_MAPSERVER));
// Цикл основного сообщения:(GetMessage (&msg, NULL, 0,
0))
{if (! TranslateAccelerator (msg. hwnd, hAccelTable,
&msg))
{TranslateMessage (&msg);(&msg);
}
}(int) msg. wParam;
}
// ФУНКЦИЯ: MyRegisterClass ()
// НАЗНАЧЕНИЕ: регистрирует класс окна.
// КОММЕНТАРИИ:
// Эта функция необходима в случае, если нужно, чтобы данный
код
// был совместим с системами Win32, не имеющими функции
RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции
важен для того,
// чтобы приложение получило "качественные" значки
и установило связь с ними.MyRegisterClass (HINSTANCE hInstance)
{WNDCLASSEX wcex;. cbSize = sizeof (WNDCLASSEX);. style=
CS_HREDRAW | CS_VREDRAW;. lpfnWndProc= WndProc;. cbClsExtra= 0;. cbWndExtra=
0;. hInstance= hInstance;. hIcon= LoadIcon (hInstance, MAKEINTRESOURCE
(IDI_MAPSERVER));. hCursor= LoadCursor (NULL, IDC_ARROW);. hbrBackground=
(HBRUSH) (COLOR_WINDOW+1);. lpszMenuName= MAKEINTRESOURCE (IDC_MAPSERVER);.
lpszClassName= szWindowClass;. hIconSm= LoadIcon (wcex. hInstance,
MAKEINTRESOURCE (IDI_SMALL));RegisterClassEx (&wcex);
}
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает
главное окно.
// КОММЕНТАРИИ:
// В данной функции дескриптор экземпляра сохраняется в
глобальной переменной,
а также создается и выводится на экран главное окно
программы.InitInstance (HINSTANCE hInstance, int nCmdShow)
{ HWND hWnd;= hInstance; // Сохранить дескриптор экземпляра в
глобальной переменной= CreateWindow (szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW,_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance,
NULL);(! hWnd)
{ return FALSE;
}(hWnd, nCmdShow);(hWnd);TRUE;
}__stdcall VvodThreadFunc (void * arg) // Поток ожидания
данных от клиентов
{while (Working)
{WaitForSingleObject (hEventVvod, INFINITE); // Ждем своего
события(hServerMutex, INFINITE); // Ждем доступа к памяти
// данные готовы, вывод на экран(hwndEdit, WM_SETTEXT, 0,
(LPARAM) lpD->Buf);(hServerMutex); // Разрешаем записывать в общую память
}
_endthreadex (0);0;
};
// ФУНКЦИЯ: WndProc (HWND, UINT, WPARAM, LPARAM)
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
// WM_COMMAND - обработка меню приложения
// WM_PAINT-Закрасить главное окно
// WM_DESTROY - ввести сообщение о выходе и
вернуться.CALLBACK WndProc (HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{int wmId, wmEvent;ps;hdc;ss [80];(message)
{case WM_CREATE:= CreateFileMapping (_HANDLE_VALUE, //
использование файла подкачки, // защита по умолчанию_READWRITE, // доступ к
чтению/записи
, // макс. размер объекта_SIZE, // размер буфера
"myFileMapping"); // имя отраженного в памяти
объекта(hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{ MessageBox (hWnd,
"Не может создать отраженный в памяти объект (%d).
\n",
"Map", MB_OK);0;
}= (D*) MapViewOfFile (hMapFile, // дескриптор отраж. в
памяти объекта_MAP_ALL_ACCESS, // разрешение чтения/записи
, 0, BUF_SIZE);(lpD == NULL)
{ MessageBox (hWnd,
"Представление проецированного файла не возможно (%d).
\n",
"Map",MB_OK);0;
}= CreateMutexA (NULL, true, nameMutex);(hServerMutex ==
NULL) MessageBox (hWnd, "Error mutex", "Map",MB_OK);
// Создаем событиe с автосбросом, со сброшенным начальным состоянием=
CreateEvent (NULL, FALSE, TRUE, nameEvent);= CreateWindow (TEXT
("EDIT"), NULL,_CHILD | WS_VISIBLE | WS_VSCROLL |_LEFT | ES_MULTILINE
| ES_AUTOVSCROLL,
, 40, 500, 400, hWnd, NULL, hInst, NULL);
// Создаем поток[0] = (HANDLE) _beginthreadex (NULL,0,&VvodThreadFunc,0,0,&uThreadIDs
[0]);(hServerMutex);;WM_COMMAND:= LOWORD (wParam);= HIWORD (wParam);(wmId)
{case IDM_ABOUT:(hInst, MAKEINTRESOURCE (IDD_ABOUTBOX), hWnd,
About);;IDM_EXIT:(hWnd);;:DefWindowProc (hWnd, message, wParam, lParam);
};WM_PAINT:= BeginPaint (hWnd, &ps);
// TODO: Add any drawing code here.(hWnd,
&ps);;WM_DESTROY:(hThreads [0]);(lpD);(hMapFile);(0);;:DefWindowProc (hWnd,
message, wParam, lParam);
}0;
}
// Обработчик сообщений для окна "О программе"._PTR
CALLBACK About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER (lParam);(message)
{case WM_INITDIALOG:(INT_PTR) TRUE;WM_COMMAND:(LOWORD
(wParam) == IDOK || LOWORD (wParam) == IDCANCEL)
{EndDialog (hDlg, LOWORD (wParam));(INT_PTR) TRUE;
};
}(INT_PTR) FALSE;
}
Приложение Б
Распечатка программы-клиента №1
// client_1. cpp: определяет точку входа для приложения.
#include "stdafx. h"
#include "client_1. h"
#include <stdio. h>
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024
// Глобальные переменные:hInst; // текущий экземплярszTitle
[MAX_LOADSTRING]; // Текст строки заголовкаszWindowClass [MAX_LOADSTRING]; //
имя класса главного окнаnameMutex = "Global\\MapMutex";nameEvent =
"Global\\MapEvent";hServerMutex; // дескриптор мьютекса на доступ к
буферу памятиhEventVvod; // дескриптор события "Данные
готовы"hMapFile;szBuf [512];D{Buf [1024];
};* lpD;Podkluchen=false;mess [2048];* m_mess = mess;HWND
hwndEdit;menuW;fMouse;function_kl (HWND hWnd)
{ // Определение длины текста в поле редактированияcbWritten
= SendMessage (hwndEdit,WM_GETTEXTLENGTH,0,0);(hwndEdit, WM_GETTEXT, (WPARAM)
cbWritten, (LPARAM) szBuf);
// Отсылаем введенную строку на сервер(m_mess, szBuf, strlen
(szBuf) + 1,&cbWritten,m_mess);(m_mess,
"%s\n\r\n",m_mess);=GetSystemMetrics (SM_CYMENU); // ширина полосы
меню в пикселях(m_mess, "%s\nШирина полосы меню: %d
px\r\n",m_mess,menuW);= GetSystemMetrics (SM_MOUSEPRESENT); // наличие
мыши в системе(fMouse)(m_mess, "%sМышь присутствует в системе.
\r\n",m_mess);(m_mess, "%sМышь отсутствует в системе. \r\n",m_mess);;
}
// Отправить объявления функций, включенных в этот модуль
кода:(HINSTANCE hInstance);(HINSTANCE, int);CALLBACKWndProc (HWND, UINT,
WPARAM, LPARAM);_PTR CALLBACKAbout (HWND, UINT, WPARAM, LPARAM);APIENTRY
_tWinMain (HINSTANCE hInstance,hPrevInstance,lpCmdLine,nCmdShow)
{UNREFERENCED_PARAMETER (hPrevInstance);_PARAMETER
(lpCmdLine);
// TODO: разместите код здесь.msg;hAccelTable;
// Инициализация глобальных строк(hInstance, IDS_APP_TITLE,
szTitle, MAX_LOADSTRING);(hInstance, IDC_CLIENT_1, szWindowClass,
MAX_LOADSTRING);(hInstance);
// Выполнить инициализацию приложения:(! InitInstance
(hInstance, nCmdShow))
{return FALSE;
}= LoadAccelerators (hInstance, MAKEINTRESOURCE
(IDC_CLIENT_1));
// Цикл основного сообщения:(GetMessage (&msg, NULL, 0,
0))
{if (! TranslateAccelerator (msg. hwnd, hAccelTable,
&msg))
}
}(int) msg. wParam;
}
// ФУНКЦИЯ: MyRegisterClass ()
// НАЗНАЧЕНИЕ: регистрирует класс окна.
// КОММЕНТАРИИ:
// Эта функция необходима только в случае, если нужно, чтобы
данный
// код был совместим с системами Win32, не имеющими функции
RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции
важен для того,
// чтобы приложение получило "качественные" значки
и установило связь с ними.MyRegisterClass (HINSTANCE hInstance)
{WNDCLASSEX wcex;. cbSize = sizeof (WNDCLASSEX);. style=
CS_HREDRAW | CS_VREDRAW;. lpfnWndProc= WndProc;. cbClsExtra= 0;. cbWndExtra=
0;. hInstance= hInstance;. hIcon= LoadIcon (hInstance, MAKEINTRESOURCE
(IDI_CLIENT_1));. hCursor= LoadCursor (NULL, IDC_ARROW);. hbrBackground=
(HBRUSH) (COLOR_WINDOW+1);. lpszMenuName= MAKEINTRESOURCE (IDC_CLIENT_1);.
lpszClassName= szWindowClass;. hIconSm= LoadIcon (wcex. hInstance,
MAKEINTRESOURCE (IDI_SMALL));RegisterClassEx (&wcex);
}
// ФУНКЦИЯ: InitInstance (HINSTANCE, int)
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает
главное окно.
// КОММЕНТАРИИ:
// В данной функции дескриптор экземпляра сохраняется в
глобальной переменной,
// а также создается и выводится на экран главное окно
программы.InitInstance (HINSTANCE hInstance, int nCmdShow)
{ HWND hWnd;= hInstance; // Сохранить дескриптор экземпляра в
глобальной переменной= CreateWindow (szWindowClass, // szTitle,
"Клиент №1",WS_OVERLAPPEDWINDOW,_USEDEFAULT, 0,
400, 250, NULL, NULL, hInstance, NULL);(! hWnd)
{ return FALSE;
}(hWnd, nCmdShow);(hWnd);TRUE;
}
// ФУНКЦИЯ: WndProc (HWND, UINT, WPARAM, LPARAM)
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
// WM_COMMAND - обработка меню приложения
// WM_PAINT-Закрасить главное окно
// WM_DESTROY - ввести сообщение о выходе и
вернуться.CALLBACK WndProc (HWND hWnd, UINT message,wParam, LPARAM lParam)
{int wmId, wmEvent;ps;hdc;j;(message)
{case WM_CREATE:= CreateWindow ( // Создаем доч. окно для
вывода данных от процессов("EDIT"), TEXT ("Клиент #1. Сообщение:
\r\n"),_CHILD | WS_VISIBLE | WS_VSCROLL |_LEFT | ES_MULTILINE |
ES_AUTOVSCROLL,
, 10, 400, 200, hWnd, NULL, hInst, NULL);;WM_COMMAND:= LOWORD
(wParam);= HIWORD (wParam);
// Parse the menu selections:(wmId)
{case IDM_ABOUT:(hInst, MAKEINTRESOURCE (IDD_ABOUTBOX), hWnd,
About);;ID_32771: // пункт меню "Подключиться"(Podkluchen) return 0;=
OpenFileMapping (_MAP_ALL_ACCESS, // доступ к чтению/записи, // имя не
наследуется
"myFileMapping"); // имя "проецируемого "
объекта(hMapFile == NULL)
{(hWnd,
"Невозможно открыть объект проекция файла",
"Клиент",MB_OK);=false;0;
}= (D*) MapViewOfFile (hMapFile, // дескриптор
"проец." объекта_MAP_ALL_ACCESS, // разрешение чтения/записи
, 0, BUF_SIZE);(lpD == NULL)
{ MessageBox (hWnd,
"Представление проецированного файла невозможно (%d).
\n",
"Клиент",MB_OK);=false;0;
}= CreateMutexA (NULL, true, nameMutex);(hServerMutex ==
NULL) MessageBox (hWnd, "Error mutex",
"Map",MB_OK);
// Откр. событиe с автосбросом, со сброшенным начальным
состоянием= OpenEvent (EVENT_ALL_ACCESS, FALSE, nameEvent);=true;;ID_32772: //
пункт меню "послать сообщение"(Podkluchen)
{FillMemory (lpD->Buf,1024,0); // очистка буфера_kl
(hWnd);(int j=0; j<sizeof (mess); j++)>Buf [j] =m_mess
[j];(hEventVvod);(hServerMutex);
}(hWnd,
"Надо подключиться к серверу\n",
"Клиент1", MB_OK);;IDM_EXIT:(hWnd);;:DefWindowProc (hWnd, message,
wParam, lParam);
};WM_PAINT:= BeginPaint (hWnd, &ps);
// TODO: Add any drawing code here.(hWnd,
&ps);;WM_DESTROY:(lpD);(hMapFile);(hServerMutex);(0);;:DefWindowProc (hWnd,
message, wParam, lParam);
}0;
}
// Обработчик сообщений для окна "О программе"._PTR
CALLBACK About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER (lParam);(message)
{case WM_INITDIALOG:(INT_PTR) TRUE;WM_COMMAND:(LOWORD
(wParam) == IDOK || LOWORD (wParam) == IDCANCEL)
{EndDialog (hDlg, LOWORD (wParam));(INT_PTR) TRUE;
};
}(INT_PTR) FALSE;
}
Распечатка функции function_kl программы-клиента
№2function_kl (HWND hWnd)
{
// Определение длины текста в поле редактированияcbWritten =
SendMessage (hwndEdit,WM_GETTEXTLENGTH,0,0);(hwndEdit, WM_GETTEXT, (WPARAM)
cbWritten, (LPARAM) szBuf);
// Отсылаем введенную строку на сервер(m_mess, szBuf, strlen
(szBuf) + 1,&cbWritten,m_mess);(m_mess,
"%s\n\r\n",m_mess);=GetSystemMetrics (SM_CXVSCROLL);a=scr;=GetSystemMetrics
(SM_CYVSCROLL);b=scr;(m_mess, "%sШирина и высота кнопки полосы прокрутки:
%d x %d\r\n",m_mess,a, b);=GetSystemMetrics
(SM_CXICON);=menuW;=GetSystemMetrics (SM_CYICON);=menuW;(m_mess, "%sШирина
и высота иконки приложения: %d x %d px\r\n",m_mess,a, b);;
}