![](/user_photo/70702_HIvw5.jpg)
- •Курсовая работа
- •Задание на курсовую работу
- •Дополнительные задания
- •Введение
- •Основная часть
- •Постановка задачи
- •Краткие теоретические основы разрабатываемой темы
- •Разработка и описание алгоритма работы приложения
- •Описание структуры программы
- •Руководство пользователя
- •Результаты применения программы
- •Заключение
- •Список литературы
Описание структуры программы
В серверной части приложения определена функция, отвечающая за передачу данных клиенту. Используются функции MessageForConsoleServer, GetCurPos, SentMessages, setlocale, connection, и другие.
В клиентской части также определена функция, отвечающая за отправку запроса на сервер и вывод полученного ответа.
Руководство пользователя
Прежде всего необходимо запустить оба сервера, иначе данные не будут получены клиентом. В открывшейся консоли клиента для соединения с первым сервером надо ввести цифру «1» и нажать «Enter», на экран будет выведена информация о последней ошибке, текущем положении курсора. Для продолжения нажать кнопку «Enter». Далее для соединения со вторым сервером надо ввести цифру «2» и нажать «Enter», на экран будет выведена информация об используемой физической памяти и виртуальной памяти.
Результаты применения программы
Рисунок 1 – Результат работы программы с двумя клиентами
Заключение
В ходе выполнения курсовой работы мы изучили методы разработки клиент-серверных приложений, а также механизмы обмена данными и средства синхронизации процессов в Windows NT с их особенностями применения на практике. Разобрали функции Win32 API для получения системной информации, информации о процессах и потоках, состоянии памяти, серверные приложения и приложение-клиент, обменивающиеся данными через заданный интерфейс. И оформили результаты выполнения курсовой работы в виде пояснительной записки в соответствии с предъявляемыми требованиями.
Список литературы
Э.Таненбаум. Современные операционные системы. 3-изд. – СПб.: Питер, 2011
Э.Таненбаум, Х.Бос. Современные операционные системы. 4-изд. – СПб.: Питер, 2015
В.Г.Олифер, Н.А.Олифер. Сетевые операционные системы. – СПб.: Питер, 2009
С.В. Назаров, А.И. Широков. «Современные операционные системы». — М., Бином, 2013
Марк Руссинович, Дэвид Соломон, Алекс Ионеску, Павел Йосифович. Внутреннее устройство Windows.7-е издание . - СПб.: Питер, 2018
Вдовикина Н.В., Машечкин И.В., Терехин А.Н., Томилин А.Н. «Операционные системы: взаимодействие процессов: учебно-методическое пособие». — Издательский отдел факультета ВМиК МГУ, 2008
Код клиента
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <string>
using namespace std;
#pragma warning(disable: 4996)
const char* IPAdressServa1 = "127.0.0.1";
const char* IPAdressServa2 = "127.0.0.2";
const u_short PortServa1 = 1111;
const u_short PortServa2 = 1112;
bool ProvOnConnection1 = false;
bool ProvOnConnection2 = false;
void CreateConnect(int numServ) {
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.s_addr = numServ== 1 ? inet_addr(IPAdressServa1) : inet_addr(IPAdressServa2);
addr.sin_port = numServ == 1 ? htons(PortServa1) : htons(PortServa2);
addr.sin_family = AF_INET;
SOCKET Connection = socket(AF_INET,SOCK_STREAM,NULL);
if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) {
cout << "Не удалось подключиться к серверу.\n";
return;
}
if (numServ == 1) ProvOnConnection1 = true;
else ProvOnConnection2 = true;
cout << "Будет производиться получение данных с сервера №" << numServ<<"\n";
char newmessage[256];
while (true) {
if (recv(Connection, newmessage, sizeof(newmessage), NULL) == SOCKET_ERROR)break;
else cout<<newmessage << endl;
}
}
void ClientsMenu() {
int result;
cin >> result;
switch (result)
{
case 1: {
if (!ProvOnConnection1) {
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CreateConnect, (LPVOID)(1), NULL, NULL);
}
else cout << "Подключение уже установлено";
ClientsMenu();
break;
}
case 2: {
if (!ProvOnConnection2) {
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CreateConnect, (LPVOID)(2), NULL, NULL);
}
else cout << "Подключение уже установлено";
ClientsMenu();
break;
}
default:
ClientsMenu();
break;
}
}
int main(int argc, char* argv[]) {
setlocale(LC_ALL, "Russian");
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) exit(1);
cout << "\nКурсовая работа\nДля подключения к серверам используйте цифры 1 и 2\n";
ClientsMenu();
system("pause");
return 0;
}
Код первого сервера
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <string>
#include <ctime>
#include <chrono>
using namespace std;
#pragma warning(disable: 4996)
const int MaxConnection = 30;
SOCKET ArrayConnection[MaxConnection];
int Errors[MaxConnection];
string CursorPositions[MaxConnection];
void MessageForConsoleServer() {
auto timeNow = chrono::system_clock::now();
time_t timeSentToClientMessage = chrono::system_clock::to_time_t(timeNow);
cout << "Отправил сообщение " << ctime(&timeSentToClientMessage) << "\n";
}
string GetCurPos() {
POINT cursPos;
GetCursorPos(&cursPos);
return "Текущие координаты курсора: [" + to_string(cursPos.x) + ";" + to_string(cursPos.y) + "]\n";
}
void SentMessages(int ind) {
Errors[ind] = GetLastError();
CursorPositions[ind] = GetCurPos();
string result = "Код последней ошибки = " + to_string(Errors[ind]) + "\n" + CursorPositions[ind];
char message[256];
strcpy(message, result.c_str());
send(ArrayConnection[ind], message, sizeof(message), NULL);
MessageForConsoleServer();
while (true) {
Sleep(1500);
int newError = GetLastError();
string newCurPos = GetCurPos();
if (Errors[ind] != newError) {
Errors[ind] = newError;
string newRes = "\nОбновленные данные с первого сервера о коде последней ошибки:\nКод последней ошибки = " + to_string(Errors[ind]);
strcpy(message, newRes.c_str());
if (send(ArrayConnection[ind], message, sizeof(message), NULL) != SOCKET_ERROR)MessageForConsoleServer();
else break;
}
if (CursorPositions[ind] != newCurPos) {
CursorPositions[ind] = newCurPos;
string newRes = "\nОбновленные данные с первого сервера о координатах курсора:\n" + CursorPositions[ind];
strcpy(message, newRes.c_str());
if (send(ArrayConnection[ind], message, sizeof(message), NULL) != SOCKET_ERROR)MessageForConsoleServer();
else break;
}
}
}
int main(int argc, char* argv[]) {
HANDLE hMutex = CreateMutex(NULL, TRUE, L"Mutex1");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
cout << "Сервер уже работает!";
exit(0);
}
setlocale(LC_ALL, "Russian");
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) exit(1);
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(1111);
addr.sin_family = AF_INET;
SOCKET sListen = socket(AF_INET,SOCK_STREAM,NULL);
bind(sListen,(SOCKADDR*)&addr,sizeof(addr));
listen(sListen, MaxConnection);
SOCKET newConnection;
for (int i = 0; i < MaxConnection; i++) {
newConnection = accept(sListen, (SOCKADDR*)&addr, &sizeofaddr);
if (newConnection != 0) {
cout << "Подключился клиент с номером: "<<i+1<<"\n";
ArrayConnection[i] = newConnection;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SentMessages, (LPVOID)(i), NULL, NULL);
}
}
system("pause");
return 0;
}
Код второго сервера
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <string>
#include <ctime>
#include <chrono>
using namespace std;
#pragma warning(disable: 4996)
const int MaxConnection = 30;
SOCKET ArrayConnection[MaxConnection];
string ArrayPhysProcents[MaxConnection];
string ArrayVirtualProcents[MaxConnection];
void MessageForConsoleServer() {
auto timeNow = chrono::system_clock::now();
time_t timeSentToClientMessage = chrono::system_clock::to_time_t(timeNow);
cout << "Отправил сообщение " << ctime(&timeSentToClientMessage) << "\n";
}
string CreateStringInformation(bool isPrys) {
MEMORYSTATUSEX Status;
Status.dwLength = sizeof(Status);
GlobalMemoryStatusEx(&Status);
if (isPrys) {
return "Приблизительный процент используемой физической памяти : " + to_string(Status.dwMemoryLoad) + " % \n";
}
else {
int TotalVirtual = Status.ullTotalVirtual/1024;
int AvailVirtual = Status.ullAvailVirtual/1024;
int OccupiedVirtual = TotalVirtual - AvailVirtual;
double a = TotalVirtual / 100;
double b = OccupiedVirtual / a;
char buff[256];
sprintf(buff, "Приблизительный процент используемой виртуальной памяти : %.2f % \n", b);
return buff;
}
}
void SentMessages(int index) {
ArrayPhysProcents[index] = CreateStringInformation(true);
ArrayVirtualProcents[index] = CreateStringInformation(false);
string result = ArrayPhysProcents[index] + ArrayVirtualProcents[index];
char messageArray[256];
strcpy(messageArray, result.c_str());
send(ArrayConnection[index], messageArray, sizeof(messageArray), NULL);
MessageForConsoleServer();
while (true) {
Sleep(1500);
string newPhys = CreateStringInformation(true);
string newVirtual = CreateStringInformation(false);
if (ArrayPhysProcents[index] != newPhys) {
ArrayPhysProcents[index] = newPhys;
string newRes = "\nОбновленные данные со второго сервера о физической памяти с сервера: \n" + ArrayPhysProcents[index];
strcpy(messageArray, newRes.c_str());
if (send(ArrayConnection[index], messageArray, sizeof(messageArray), NULL) != SOCKET_ERROR) MessageForConsoleServer();
else break;
}
if (ArrayVirtualProcents[index] != newVirtual) {
ArrayVirtualProcents[index] = newVirtual;
string newRes = "\nОбновленные данные со второго сервера о виртуальной памяти с сервера: \n" + ArrayVirtualProcents[index];
strcpy(messageArray, newRes.c_str());
if (send(ArrayConnection[index], messageArray, sizeof(messageArray), NULL) != SOCKET_ERROR) MessageForConsoleServer();
else break;
}
}
}
int main(int argc, char* argv[]) {
HANDLE hMutex = CreateMutex(NULL, TRUE, L"Mutex2");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
cout<< "Сервер уже работает!";
exit(0);
}
setlocale(LC_ALL, "Russian");
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) exit(1);
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.2");
addr.sin_port = htons(1112);
addr.sin_family = AF_INET;
SOCKET sListen = socket(AF_INET,SOCK_STREAM,NULL);
bind(sListen,(SOCKADDR*)&addr,sizeof(addr));
listen(sListen, MaxConnection);
SOCKET newConnection;
for (int i = 0; i < MaxConnection; i++) {
newConnection = accept(sListen, (SOCKADDR*)&addr, &sizeofaddr);
if (newConnection != 0) {
cout << "Подключился клиент с номером: " << i + 1 << "\n";
ArrayConnection[i] = newConnection;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SentMessages, (LPVOID)(i), NULL, NULL);
}
}
system("pause");
return 0;
}