Федеральное государственное образовательное бюджетное учреждение
высшего профессионального образования
----------------------------------------------------------------------------------------------------
Кафедра Математической кибернетики и информационных технологий
КУРСОВАЯ РАБОТА
по дисциплине
ОПЕРАЦИОННЫЕ СИСТЕМЫ
на тему:
«ИССЛЕДОВАНИЕ МЕХАНИЗМОВ МЕЖПРОЦЕССНОГО ВЗАИМОДЕЙСТВИЯ»
Выполнил:
студент Алгазин П.В.
Группа БФИ1601
Проверил:
Королькова Т.В.
ст. пр. кафедры МКиИТ)
Оценка_________________________
Дата ___________________________
Москва 2018
Оглавление
1. Задание 3
2. Введение 4
3. Основная часть 5
3.1 Постановка задачи 5
3.2 Краткие теоретические основы разрабатываемой темы 5
3.3 Разработка и описание алгоритма работы приложения 5
3.4 Описание структуры программы 6
3.5 Руководство пользователя 6
3.6 Результаты применения программы 6
4. Заключение 8
5. Список использованных источников 9
6. Приложение А 10
Разработать многозадачное приложение, выполняющее получение, сбор и вывод системной информации в соответствии с вариантом задания. Номер варианта задания на курсовую работу совпадает с номером, под которым записана фамилия студента в журнале группы.
№ вар. |
Способ коммуникации |
Процесс 1 определяет и передает |
Процесс 2 определяет и передает |
1 |
Отображение файлов |
- имя компьютера, имя пользователя; - версию операционной системы |
- процент используемой физической памяти; - процент используемой виртуальной памяти |
Межпроцессное взаимодействие — обмен данными между потоками одного или разных процессов. Реализуется посредством механизмов, предоставляемых ядром ОС или процессом, использующим механизмы ОС и реализующим новые возможности IPC. Может осуществляться как на одном компьютере, так и между несколькими компьютерами сети.
Из механизмов, предоставляемых ОС и используемых для IPC, можно выделить:
механизмы обмена сообщениями;
механизмы синхронизации;
механизмы разделения памяти;
механизмы удалённых вызовов (RPC).
Для оценки производительности различных механизмов IPC используют следующие параметры:
пропускная способность (количество сообщений в единицу времени, которое ядро ОС или процесс способно обработать);
задержки (время между отправкой сообщения одним потоком и его получением другим потоком).
IPC может называться терминами межпотоковое взаимодействие (англ. inter-thread communication) и межпрограммное взаимодействие (англ. inter-application communication).
Межпроцессное взаимодействие, наряду с механизмами адресации памяти, является основой для разграничения адресного пространства между процессами.
Понимание принципов межпроцессного взаимодействие является очень важным, поэтому в ходе данной курсовой работы нами будет рассмотрен один из способов межпроцессного взаимодействия – сокеты.
Целью данной курсовой работы является закрепление и углубление теоретических знаний в области современных операционных систем, приобретение практических навыков разработки клиент-серверных приложений, использующих стандартные механизмы межпроцессного взаимодействия.
«Клиент — сервер» (англ. client–server) — вычислительная или сетевая архитектура, в которой задания или сетевая нагрузка распределены между поставщиками услуг, называемыми серверами, и заказчиками услуг, называемыми клиентами. Фактически клиент и сервер — это программное обеспечение. Обычно эти программы расположены на разных вычислительных машинах и взаимодействуют между собой через вычислительную сеть посредством сетевых протоколов, но они могут быть расположены также и на одной машине. Программы-серверы ожидают от клиентских программ запросы и предоставляют им свои ресурсы в виде данных (например, загрузка файлов посредством HTTP, FTP, BitTorrent, потоковое мультимедиа или работа с базами данных) или в виде сервисных функций (например, работа с электронной почтой, общение посредством систем мгновенного обмена сообщениями или просмотр web-страниц во всемирной паутине). Поскольку одна программа-сервер может выполнять запросы от множества программ-клиентов, её размещают на специально выделенной вычислительной машине, настроенной особым образом, как правило, совместно с другими программами-серверами, поэтому производительность этой машины должна быть высокой. Из-за особой роли такой машины в сети, специфики её оборудования и программного обеспечения, её также называют сервером, а машины, выполняющие клиентские программы, соответственно, клиентами.
Преимущества
Отсутствие дублирования кода программы-сервера программами-клиентами.
Так как все вычисления выполняются на сервере, то требования к компьютерам, на которых установлен клиент, снижаются.
Все данные хранятся на сервере, который, как правило, защищён гораздо лучше большинства клиентов. На сервере проще организовать контроль полномочий, чтобы разрешать доступ к данным только клиентам с соответствующими правами доступа.
Недостатки
Неработоспособность сервера может сделать неработоспособной всю вычислительную сеть. Неработоспособным сервером следует считать сервер, производительности которого не хватает на обслуживание всех клиентов, а также сервер, находящийся на ремонте, профилактике и т. п.
Поддержка работы данной системы требует отдельного специалиста — системного администратора.
Высокая стоимость оборудования.
Разработка и описание алгоритма работы приложения
Сервера 1 и 2 запускаются на портах 27015 и 27016 соответственно и ожидают входящее соединение. После установления соединения передают данные клиенту.
Клиент соединяется с сервером и после получения данных разрывает соединение.
Описание структуры программы
В серверной части приложения определена функция, отвечающая за передачу данных клиенту. Используются функции send, connect, recv и другие.
В клиентской части также определена функция, отвечающая за отправку запроса на сервер и вывод полученного ответа.
Руководство пользователя
Прежде всего необходимо запустить оба сервера иначе данные не будут получены клиентом, для этого в приложениях серверов имеются соответствующие кнопки. Далее запустив клиент можно с помощью соответствующих кнопок получить данные от серверов.
Результаты применения программы
Рисунок 1 - Первый сервер
Рисунок 2 - Второй сервер
Рисунок 3 – Клиент
Заключение
В результате данной курсовой работы были закреплены и углублены теоретических знаний в области современных операционных систем, приобретены практические навыки разработки клиент-серверных приложений, использующих стандартный механизм межпроцессного взаимодействия - сокет.
Список использованных источников
Э.Таненбаум. Современные операционные системы. 3-изд. – СПб.: Питер, 2011
http://ru.wikipedia.org/wiki/Клиент-сервер
http://msdn.microsoft.com
Приложение А
первый сервер #undef UNICODE #include <stdlib.h> #include <stdio.h> #include <iostream> #pragma comment(lib, "user32.lib") using namespace std; // Need to link with Ws2_32.lib #pragma comment (lib, "Ws2_32.lib") // #pragma comment (lib, "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <winternl.h> #include <cstdio> #pragma comment (lib, "User32.lib") char recvbuf[200]; int main () { setlocale(LC_ALL, "rus"); TCHAR compname[256]; DWORD compname_len = 256; GetComputerName((TCHAR*)compname, &compname_len); TCHAR username[256]; DWORD username_len = 256; GetUserName((TCHAR*)username, &username_len); char str1[80]; sprintf(str1,"Имя компьютера: %s\nИмя пользователя: %s\n\n",compname,username); cout«str1; char str2[80]; NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); OSVERSIONINFOEXW osInfo; *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); if (NULL != RtlGetVersion) { osInfo.dwOSVersionInfoSize = sizeof(osInfo); RtlGetVersion(&osInfo); sprintf(str2,"Версия ОС: %d\n",osInfo.dwMajorVersion); cout « str2«endl; } sprintf(recvbuf,"%s%s\n",str1,str2); for(;;) { WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; char recvbuf1[200]; int recvbuflen1 = sizeof(recvbuf1); struct addrinfo *result = NULL; struct addrinfo hints; char str[100]; int iSendResult; int recvbuflen = sizeof(recvbuf); // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { sprintf(str,"WSAStartup failed with error: %d\r\n", iResult); cout«str; return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { sprintf(str,"getaddrinfo failed with error: %d\r\n", iResult); cout«str; WSACleanup(); return 1; } // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { sprintf(str,"socket failed with error: %ld\r\n", WSAGetLastError()); cout«str; freeaddrinfo(result); WSACleanup(); return 1; } // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { sprintf(str,"bind failed with error: %d\r\n", WSAGetLastError()); cout«str; freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { sprintf(str,"listen failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ListenSocket); WSACleanup(); return 1; } // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { sprintf(str,"accept failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ListenSocket); WSACleanup(); return 1; } // No longer need server socket closesocket(ListenSocket); // Receive until the peer shuts down the connection do { iResult = recv(ClientSocket, recvbuf1, recvbuflen1, 0); if (iResult > 0) { sprintf(str,"Bytes received: %d\r\n", iResult); cout«str; // Echo the buffer back to the sender iSendResult = send( ClientSocket, recvbuf, recvbuflen, 0 ); if (iSendResult == SOCKET_ERROR) { sprintf(str,"send failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ClientSocket); WSACleanup();
return 1; } sprintf(str,"Bytes sent: %d\r\n", iSendResult); cout«str; } else if (iResult == 0){ sprintf(str,"Connection closing...\r\n"); cout«str; } else { sprintf(str,"recv failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ClientSocket); WSACleanup(); return 1; } } while (iResult > 0); // shutdown the connection since we're done iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { sprintf(str,"shutdown failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ClientSocket); WSACleanup(); return 1; } // cleanup closesocket(ClientSocket); WSACleanup(); cout«"\n"; } return 0; }
второй сервер #undef UNICODE #include <stdlib.h> #include <stdio.h> #include <iostream> #pragma comment(lib, "user32.lib") using namespace std; // Need to link with Ws2_32.lib #pragma comment (lib, "Ws2_32.lib") // #pragma comment (lib, "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27016" #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <winternl.h> #include <cstdio> #pragma comment (lib, "User32.lib") char recvbuf[200]; int main () { setlocale(LC_ALL, "rus"); MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx (&statex); char str1[80]; sprintf(str1,"Процент используемой физической памяти : %d%\nПроцент используемой виртуальной памяти: %d%\n",statex.dwMemoryLoad,((statex.ullTotalVirtual-statex.ullAvailVirtual)/(statex.ullTotalVirtual/100))); cout«str1«endl; sprintf(recvbuf,"%s\n",str1); for(;;) { WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; char recvbuf1[200]; int recvbuflen1 = sizeof(recvbuf1); struct addrinfo *result = NULL; struct addrinfo hints; char str[100]; int iSendResult; int recvbuflen = sizeof(recvbuf); // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { sprintf(str,"WSAStartup failed with error: %d\r\n", iResult); cout«str; return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { sprintf(str,"getaddrinfo failed with error: %d\r\n", iResult); cout«str; WSACleanup(); return 1; } // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { sprintf(str,"socket failed with error: %ld\r\n", WSAGetLastError()); cout«str; freeaddrinfo(result); WSACleanup(); return 1; } // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { sprintf(str,"bind failed with error: %d\r\n", WSAGetLastError()); cout«str; freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { sprintf(str,"listen failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ListenSocket); WSACleanup(); return 1; } // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { sprintf(str,"accept failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ListenSocket); WSACleanup(); return 1; } // No longer need server socket closesocket(ListenSocket); // Receive until the peer shuts down the connection do { iResult = recv(ClientSocket, recvbuf1, recvbuflen1, 0); if (iResult > 0) { sprintf(str,"Bytes received: %d\r\n", iResult); cout«str; // Echo the buffer back to the sender iSendResult = send( ClientSocket, recvbuf, recvbuflen, 0 ); if (iSendResult == SOCKET_ERROR) { sprintf(str,"send failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ClientSocket); WSACleanup(); return 1; } sprintf(str,"Bytes sent: %d\r\n", iSendResult); cout«str; } else if (iResult == 0){ sprintf(str,"Connection closing...\r\n"); cout«str; } else { sprintf(str,"recv failed with error: %d\r\n", WSAGetLastError()); cout«str; closesocket(ClientSocket); WSACleanup(); return 1; }