- •Пояснительная записка
- •1 Описание метода решения задачи
- •1.1 Исходные данные (технические требования) на проектирование
- •1.2 Mpi (Message Passing Interface)
- •2 Описание глобальных переменных
- •3 Спецификации на программные модули
- •3.1 Модуль Main.Cpp
- •3.2 Модуль Server.Cpp
- •8 Руководство пользователя
- •Приложение а. Листинг программного текста.
- •Модуль Server.Cpp
- •Приложение б. Uml Диаграммы.
- •Приложение в. Результаты работы программ.
8 Руководство пользователя
После запуска программы на экран выводится информация о номере процесса и результате подключения к базе данных. В случае успешного подключения пользователю предоставляется возможность совершить SQL – запрос либо попросту выйти из приложения. Далее серверы принимают запрос и после того как обработают его они перешлют результаты клиенту – инициатору SQL – запроса. Результат выводиться на экран и записывается в базу данных клиента. После успешного SQL – запроса можно выполнить новую команду.
Заключение
В ходе выполнения курсового проекта была разработана распределительная вычислительная система с базой данных. Клиенты взаимодействуют между собой таким образом, что каждый из них может получить любые данные из сети, так как будто они находятся на его собственном узле. База данных разработана в программной системе разработки баз данных Microsoft Access, что позволяет легко понять ее организацию и простоту управления. Получить необходимую информацию из базы данных можно, используя SQL - запросы.
Разработка проводилась на языке программирования С++ в среде Microsoft Visual Studio 2010 Console Application.
Проведённое тестирование показало правильность работы программ. Разработка проведена с использованием операционной системы Windows 7 на ПК с процессором Phenom II.
Список используемой литературы
Уильям Гропп (William Gropp), Юинг Ласк (Ewing Lusk), Энтони Скъеллум (Anthony Skjellum), Использование MPI, изд-во MIT Press, 1994
С.А.Зинкин. Курс лекций по курсу «Методы и средства обработки данных»
Р.Д. Верма «Справочник по функциям Win32 API»
Среда выполнения задач "разветвление-объединение" Дага Ли (Doug Lea) util.concurrent,
Т.А. Павловская «С/С++ Программирование на языке высокого уровня», Питер 2007 г
www.ru.wikipedia.org
Приложение а. Листинг программного текста.
Модуль Extern.h
// Extern.h
extern MPI_Status Status;
extern int ProcNum, ProcRank;
Модуль GlobVar.h
// GlobVar.h
int ProcNum, ProcRank;
MPI_Status Status;
Модуль Header.h
// Header.h
#ifndef HEADER_H
#define HEADER_H
#include <WinSock2.h>
#include <Windows.h>
using namespace std;
#include <locale.h>
#include <sql.h>
#include <sqlext.h>
#include "mpi.h"
#include <conio.h>
#include <process.h>
#include <stdio.h>
#include <mbstring.h>
#include <iostream>
#define SIZE_BUF 1024
int DoClientProcess();
int DoServerProcess();
#endif /* HEADER_H */
Модуль Main.cpp
// MISOD_Kurs_Novikov
#include "Header.h"
#include "GlobVar.h"
int main(int argc, char* argv[])
{
setlocale(LC_ALL, "Rus");
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum); // количество процессов
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank); // ранг процесса
printf("\n Hello from process %3d\n\n", ProcRank);
//клиент
if ( ProcRank == 0 )
{
DoClientProcess();
}
//сервер
else
{
DoServerProcess();
}
MPI_Finalize();
getch();
return 0;
}
Модуль Client.cpp
// Client.cpp
#include "Header.h"
#include "Extern.h"
int DoClientProcess()
{
cout << "----- Client -----" << endl;
//------------------ Соединение клиента с БД (пока пустая) -------------
HSTMT hstmt; //идентификатор оператора
HDBC hdbc; //идентификатор соединения
HENV henv; //идентификатор среды
SQLRETURN retcode;
char dbase[]="Storage"; //имя БД
char user[]=""; //имя пользователя
char passwd[]=""; //пароль пользователя
SQLINTEGER sStorageID;
SQLCHAR szName[SIZE_BUF];
SQLINTEGER sSeries;
SQLCHAR szColor[SIZE_BUF];
SQLINTEGER sYear;
SQLINTEGER sCost;
SQLINTEGER cbStorageID;
SQLINTEGER cbName;
SQLINTEGER cbSeries;
SQLINTEGER cbColor;
SQLINTEGER cbYear;
SQLINTEGER cbCost;
//Назаначение идентификатора среды
retcode=SQLAllocEnv(&henv);
if (SQL_SUCCESS!=retcode)
{
printf("HENV Error! Exit\n");
_getch();
return -1;
}
//назначение идентификатора соединения
retcode=SQLAllocConnect(henv,&hdbc);
if (SQL_SUCCESS!=retcode)
{
printf("HDBC Error! Exit\n");
SQLFreeEnv(henv);
_getch();
return -1;
}
cout << "Connecting to DataBase...";
retcode=SQLConnect(hdbc,(SQLCHAR*)dbase,
SQL_NTS,(SQLCHAR*)user,
SQL_NTS,(SQLCHAR*)passwd,
SQL_NTS);
if (SQL_SUCCESS != retcode)
{
printf("Problem with connect to DB! Exit\n");
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
_getch();
return -1;
}
cout << "DONE!" << endl;
retcode=SQLAllocStmt(hdbc,&hstmt);
if(SQL_SUCCESS!=retcode)
{
printf("HSTMT Error! Exit\n");
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
_getch();
return -1;
}
// для SQL-запроса
char Storage_Id[50];
char Name[50];
char Number[50];
char avtor[50];
char year[50];
char Cost[50];
//------------- Цикл работы клиента --------------------
while(1)
{
char *SQLString = new char[50];
cout << "\nInput SQL-query to Server DB: ";
gets(SQLString);
cout << "\nYour SQL-query: " << SQLString << endl;
int countSend = strlen(SQLString);
cout << "countSend = " << countSend << endl;
for (int i=1; i<ProcNum; i++) // отправляем SQL-запрос к БД всех серверов
{
MPI_Send(&countSend, 1, MPI_INT, i, ProcRank, MPI_COMM_WORLD); // количество отправляемых символов
MPI_Send(SQLString, countSend, MPI_CHAR, i, ProcRank, MPI_COMM_WORLD); // тег - ProcRank
}
if (!strcmp(SQLString, "exit")) break;
// принимаем результат от серверов
char **mesRecv = new char*[1024]; // не более 1024 строк как результат SQL-запроса
for (int i=1; i<ProcNum; i++) // отправляем SQL-запрос к БД всех серверов
{
int countStrRec = 0;
MPI_Recv(&countStrRec, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
//printf("countStrRec = %d", &countStrRec);
cout << endl << endl << "countStrRec = " << countStrRec << endl;
for (int j=0; j<countStrRec; j++)
{
int lenRecv = 0;
mesRecv[j] = new char[SIZE_BUF];
MPI_Recv(&lenRecv, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
MPI_Recv(mesRecv[j], lenRecv, MPI_CHAR, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
cout << mesRecv[j];
// Разбиваем строку, полученную от сервера
int i = 0;
while((*(mesRecv[j])) != 0x09) // Пробел
{
Storage_Id[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
Storage_Id[i] = '\0';
(mesRecv[j])++;
i = 0;
while((*(mesRecv[j])) != 0x09) // Пробел
{
Name[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
Name[i] = '\0';
(mesRecv[j])++;
i = 0;
while((*(mesRecv[j])) != 0x09) // Пробел
{
Number[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
Number[i] = '\0';
(mesRecv[j])++;
i = 0;
while((*(mesRecv[j])) != 0x09) // Пробел
{
avtor[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
avtor[i] = '\0';
(mesRecv[j])++;
i = 0;
while((*(mesRecv[j])) != 0x09) // Пробел
{
year[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
year[i] = '\0';
(mesRecv[j])++;
i = 0;
while((*(mesRecv[j])) != 0x09 && (*(mesRecv[j])) != 0x0a) // Пробел
{
Cost[i] = *(mesRecv[j]);
i++;
(mesRecv[j])++;
}
Cost[i] = '\0';
// Вставляем полученное в свою БД
char InsertQuery[SIZE_BUF];
sprintf(InsertQuery, "INSERT INTO Storage ([Storage_Id], [Name], [Number], [avtor], [year], [Cost])VALUES (%s, '%s', %s, '%s', %s, %s)", Storage_Id, Name, Number, avtor, year, Cost);
retcode=SQLExecDirect(hstmt,(SQLTCHAR*)(LPCTSTR)InsertQuery,strlen(InsertQuery));
if (SQL_SUCCESS != retcode)
{
printf("Problem with INSERT INTO! Exit\n");
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
_getch();
return 1;
}
}
}
}
// Закрываем соединения
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
cout << endl << endl << "End of work client.";
}