Информационно-вычислительная сеть на основе технологии клиент-сервер, предметная область: 'Диски'

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информатика, ВТ, телекоммуникации
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    166,2 Кб
  • Опубликовано:
    2012-06-22
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Информационно-вычислительная сеть на основе технологии клиент-сервер, предметная область: 'Диски'

МИНИСТЕРСТВО ОБРОЗОВАНИЯ И НАУКИ РФ

ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

Кафедра «Вычислительная техника»







Пояснительная записка

к курсовому проекту по дисциплине

«Сети ЭВМ и телекоммуникации»

Тема: «Информационно-вычислительная сеть на основе технологии клиент-сервер», предметная область: «Диски»

Автор работы: Роганов А.В.

Группа08ВВ1

Руководитель работы Зинкин С.А.



Пенза, 2012г.

Реферат

Пояснительная записка содержит 34 страницы, 12 рисунков 3 приложения.

СЕТИ ЭВМ, КЛИЕНТ, СЕРВЕР, C++, Visual Studio, MFC, ДАННЫЕ, СОКЕТЫ, IP- АДРЕС, ПОРТ, ПРОТОКОЛЫ TCP/IP.

Объектом разработки является система программ, осуществляющих взаимодействие посредством сети.

Цель работы: Разработать клиент-серверное приложение для передачи данных с использованием среды программирования Microsoft Visual Studio 2005.

Результаты: в результате проведенной работы разработана система программ, реализующая алгоритм сетевого взаимодействия приложений.

 

Оглавление:


Введение

Архитектура клиент/сервер

.1 Сокеты и библиотека WinSock

.2 Сервер

.3 Клиент

Разработка системы передачи данных в локальной вычислительной сети

.1 Анализ требований

.2 Проектирование

Реализация

.1 Реализация приложения «сервер»

.2 Реализация приложения «клиент»

База данных «диски»

Результаты работы системы

Заключение

Список использованной литературы

Приложения

Введение


Когда компьютеры были очень большими и их было очень мало, а на один большой компьютер приходилось много пользователей с еще большим числом очень маленьких задач, вопрос о перенесении программ и данных с одного компьютера на другой не играл какой-либо заметной роли.

Однако по мере совершенствования компьютеров, увеличения их числа, развития и усложнения средств программного обеспечения, в том числе и прикладного, увеличения объемов баз данных возникла насущная необходимость в соединении компьютеров между собой. Такое связывание компьютеров, позволяющее объединить их ресурсы - процессоры, память (внутреннюю и внешнюю, включая жесткие диски, разнообразные внешние устройства - принтеры, факс-аппараты, модемы и др.), каналы связи, и представляет собой вычислительную сеть, в которой каждый компьютер может передать другому компьютеру, подключенному к сети, любой набор данных.

Таким образом, вычислительная сеть, объединяющая ресурсы нескольких компьютеров, позволяет каждому их них использовать всю совокупность этих ресурсов.

Вычислительные сети строятся на основе архитектуры "клиент-сервер", которая предполагает выделение в сети так называемых "серверов" и "клиентов". К клиентам относятся рабочие станции (компьютеры) сети, которые не имеют непосредственных контактов друг с другом и могут общаться между собой только через сервер: следовательно, одна станция не может использовать файл, находящийся на другой станции: для этого файл должен находиться на файл-сервере. Серверы управляют подключенными к ним общими разделяемыми ресурсами сети. В качестве сервера может быть использован либо обычный персональный компьютер, или же это может быть специализированное устройство.

1. Архитектура клиент/сервер


         1.1 Сокеты и библиотека WinSock


Связь в сети Интернет осуществляется на основе двух протоколов - TCP (Transmission Control Protocol) и IP (Internet Protocol), оба протокола объединяются в стек-протокол - TCP/IP. Помимо этого часто используется протокол UDP (User Datagram Protocol - протокол пользовательских дейтаграмм). Для связи между двумя компьютерами должен быть создан сокет.

Сокет - механизм, позволяющий независимо от протокола передачи данных организовать сетевой интерфейс между двумя компьютерами. Обращаться к сокету можно по IP-адресу и номеру порта. Различают сокеты с установлением соединения (т. е. адреса гнезд отправителя и получателя выясняются заранее, до передачи сообщений между ними - устанавливается так называемый виртуальный канал между двумя хостами в сети) - виртуальный канал и без установления соединения (адреса сокетов отправителя и получателя передаются с каждым пересылаемым сообщением) - дейтаграмма. В первом случае для передачи данных используется протокол TCP, во втором - UDP. Таким образом, сокеты могут работать как с протоколом TCP, так и с протоколом UDP. Работа дейтаграммам осуществляется быстрее виртуальных каналов, однако их надежность передачи данных ниже.

Сокеты с установлением соединения взаимодействуют по схеме клиент/сервер. Создание связи происходит по следующей схеме. Сервер создает сокет, который пассивно слушает, ожидая запросы от другого сокета. Клиент создает сокет, который посылает запрос на соединение прослушивающему сокету. По получении запроса прослушивающий порт отвечает и устанавливается соединение. После этого программы могут обмениваться данными, то есть записывать в поток и читать из потока. Это может происходить до тех пор, пока одна из программ не закроет связь. Когда клиент подсоединяется к серверу, прослушивающий сокет не прекращает ожидание запросов от клиентов. Сервер продолжает прослушивать возможные запросы от других клиентов.

Все функции работы с сокетами описаны в заголовочном файле winsock2.h. Для успешной сборки программы необходимо указать подключаемую библиотеку ws2_32.lib. Для начала работы с сетью необходимо проинициализировать библиотеку ws2_32. Для этого используется следующая функция: int WSAStartup (unsigned int wVersionRequested, struct WSAData *lpWSAData ).

При завершении работы с сокетами необходимо вызвать функцию int WSACleanup(), которая завершает работу программы с библиотекой гнезд Ws2_32. При успешном выполнении функция возвращает 0. Если произошла ошибка, возвращается ненулевое значение.

        

         1.2 Сервер


Для того чтобы процессы-клиенты могли связаться с сервером, сервер создает сокет для обмена данными. Сокет представляет собой особый вид файла, из которого можно читать и в которой можно записывать данные. Создание сокета подразумевает вызов функции socket.

Далее осуществляется получение локального адреса, чтобы все запросы на соединения, приходящие на данную ЭВМ и обращающиеся к указанному порту, операционная система направляла данному процессу. Осуществляется вызов функции bind, в которой указывается созданный ранее сокет, IP-адрес ЭВМ и порт. В случае успеха сервер вызывает функцию listen, которая говорит операционной системе о том, что процесс ожидает поступления запросов на соединение к данному сокету.

Когда клиент вызывает функцию connect, серверу приходит запрос на соединение. Для того чтобы программа смогла вести обмен данными с клиентами и одновременно продолжать работу, сервер создает копию сокета. Таким образом создаётся новая нить, создаваемая при помощи функции _beginthread.

Далее осуществляется обмен данными. Сервер связан с БД, откуда и берётся необходимая информация. Используется СУБД MS Access. После приема данных они дешифруются.

По окончании работы с клиентом серверный процесс закрывает свою копию сокета и уничтожается.

         1.3 Клиент


Для соединения клиенту так же как и серверу необходимо создание сокета.

Подключения осуществляются только тогда, когда тот процесс ожидает приема соединения. Для установки соединения необходимо указать IP-адрес ЭВМ и порт, то есть использовать функцию connect.

Далее осуществляется приём данных. Перед осуществлением передачи данные шифруются. На принимающей стороне полученные данные дешифруются.

Разрыв соединения осуществляется при помощи функции close, которая уничтожает сокет.

 

2. Разработка системы передачи данных в локальной вычислительной сети


         2.1 Анализ требований


Необходимо разработать на языке С++ клиент-серверное приложение - систему программ, осуществляющих взаимодействие посредством локальной вычислительной сети. Графический интерфейс приложения разработать, используя библиотеку MFC. Программа должна состоять из двух частей: клиента и сервера. Сетевой интерфейс между компьютерами в сети организовать с помощью сокетов. Программа «сервер» должна отправлять сообщения всем подключенным клиентам. Использовать среду программирования MS Visual Studio.

        

         2.2 Проектирование


Исходя из требований, необходимо реализовать приложение «клиент» и приложение «сервер». Если сервер готов к работе, то он должен ожидать подключения к нему клиентов. Клиент делает запрос и принимает данные с сервера. Если сервер не готов, клиент извещается об этом.

3. Реализация


         3.1 Реализация приложения «сервер»


При запуске программы «сервер» производится инициализация библиотеки WinSock. Запускается поток прослушивания порта 250188. Вводится пароль. Выбирается источник данных - БД MS Access. Сервер ожидает обращения клиентов.

.2 Реализация приложения «клиент»

При запуске клиента инициализируется библиотека WinSock. При нажатии кнопки ОК производится попытка подключиться к сокету сервера с указанным IP адресом и портом. Если сервер не запущен, то выводится сообщение об ошибке соединения. При удачном соединении запускается поток, в котором серверу отправляется имя клиента и начинается прослушивание сокета. Клиент делает запрос. Сервер отсылает информацию клиенту. Полученные данные выводятся на экран. При работе с сервером клиент может в любой момент прервать соединение, нажав кнопку «Выход».

4. База данных «Диски»

серверный программирование локальный сеть

В магазине продаются компакт-диски различных групп. Каждая группа имеет несколько альбомов. Каждый альбом включает несколько песен. Разработана соответствующая БД. Основными конструктивными элементами инфологических моделей являются сущности, связи между ними и их свойства (атрибуты). В построенной модели имеются пять сущностей.

. disks (group, album, year, label, quantity)

Эта сущность хранит расширенную информацию о дисках.

. Pantera (album, year, label)

Эта сущность хранит информацию об альбомах группы Pantera.

3. Metallica (album, year, label)

Эта сущность хранит информацию об альбомах группы Metallica.

. Nirvana (album, year, label)

Эта сущность хранит информацию об альбомах группы Nirvana.

. Nevermind (album, song, time)

Эта сущность хранит информацию об альбоме Nevermind группы Nirvana.

Атрибуты «album», «year», «label» выполняют функцию индексной связи между сущностями, которая определяет связь между таблицами Pantera, Metallica, Nirvana - Nevermind.


Рисунок 1

5. Результаты работы системы

Проведено тестирование программы, подтверждающее правильность её работы. Ниже приведены результаты работы.

Рисунок 2 - запуск сервера

Рисунок 3 - сервер готов к работе

Рисунок 4 - подключение к серверу

Рисунок 5 - клиент получил данные

Рисунок 6

Рисунок 7 - работа с несколькими клиентами

Заключение

Разработано клиент-серверное приложение для передачи данных. Программа написана на языке С++ в среде программирования MS Visual Studio. Тестирование показало правильность работы приложения. Разработка и тестирование производились в ОС Windows XP на ПК с процессором Athlon.

Список использованной литературы

MSDN Library. Copyright 1995-2000 Microsoft Corporation.

Зинкин С.А. Курс лекций по курсу «Сети ЭВМ и телекоммуникации»

Компьютерные сети. Принципы, технологии, протоколы / В.Г. Олифер, Н.А. Олифер.-СПб.: Питер, 2002.

Сети ЭВМ: протоколы, стандарты, интерфейсы / Ю. Блэк; перев. с англ. - М.: Мир, 1990.

А. Мешков, Ю. Тихомиров «Visual C++ и MFC» - 2 издание, «BHV» - Санкт-Петербург, 1999г.

Приложения

Приложение А

 

Листинг программного текста

Сервер

#include "stdafx.h"

#include "lip_server.h"

#include "MainFrm.h"

#include "lip_serverDoc.h"

#include "lip_serverView.h"

#include "ParamDlg.h"

#include "global.h"

#include "..\crypt.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILEchar THIS_FILE[] = __FILE__;

#endif_MESSAGE_MAP(CLip_serverApp, CWinApp)

//{{AFX_MSG_MAP(CLip_serverApp)_COMMAND(ID_APP_ABOUT, OnAppAbout)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

// Standard file based document commands_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)_MESSAGE_MAP()_serverApp::CLip_serverApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}_serverApp theApp;CLip_serverApp::InitInstance()

{(!AfxSocketInit())

{(IDP_SOCKETS_INIT_FAILED);FALSE;

}d(NULL);(d.DoModal() == IDOK) {= d.m_Port;= d.m_Password;= new CDatabase();>OpenEx(NULL, 0);= new CRecordset(pLipDB);= false;(WaitingForConnect, NULL);

}false;

#ifdef _AFXDLLdControls();// Call this when using MFC in a shared DLL

#elsedControlsStatic();// Call this when linking to MFC statically

#endif(_T("Local AppWizard-Generated Applications"));(0); // Load standard INI file options (including MRU)* pDocTemplate;= new CSingleDocTemplate(_MAINFRAME,_CLASS(CLip_serverDoc),_CLASS(CMainFrame), // main SDI frame window_CLASS(CLip_serverView));(pDocTemplate);

// Parse command line for standard shell commands, DDE, file opencmdInfo;(cmdInfo);

// Dispatch commands specified on the command line(!ProcessShellCommand(cmdInfo))FALSE;

// The one and only window has been initialized, so show and update it._pMainWnd->ShowWindow(SW_SHOW);_pMainWnd->UpdateWindow();TRUE;

}CLip_serverApp::ExitInstance()

{(pLipRec) {>Close();pLipRec;

}(pLipDB) {>Close();pLipDB;

}CWinApp::ExitInstance();

}CAboutDlg : public CDialog

{:();

// Dialog Data

//{{AFX_DATA(CAboutDlg){ IDD = IDD_ABOUTBOX };

//}}AFX_DATA

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg):void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation:_MESSAGE_MAP()

{

}CAboutDlg::DoDataExchange(CDataExchange* pDX)

{::DoDataExchange(pDX);

}_MESSAGE_MAP(CAboutDlg, CDialog)_MESSAGE_MAP()

// App command to run the dialogCLip_serverApp::OnAppAbout()

{aboutDlg;.DoModal();

}WaitingForConnect( LPVOID pParam)

{

SOCKET MySocket;// основное гнездо - на которое принимаются соединения

sockaddr_inMySocketAdress;// структура данных гнездаnewSocket;// гнездо, на которое перенаправляются соединения

inta;= socket(AF_INET, SOCK_STREAM, 0); // создать гнездо

if(MySocket == INVALID_SOCKET)

{ // в случае неудачи - выдать сообщение и выйти

// cout<<endl<<"socket(...) error "<<WSAGetLastError()<<endl;0;

}.sin_family = AF_INET; // заполнение структуры данных.sin_port = htons(port);.sin_addr.s_addr = htonl(INADDR_ANY);(bind(MySocket, (sockaddr*) &MySocketAdress,(MySocketAdress)) == SOCKET_ERROR) // получение локального адреса

{ // в случае неудачи - выдать сообщение, закрыть гнездо и выйти

// cout<<endl<<"bind(...) error "<<WSAGetLastError()<<endl;(MySocket);0;

}(listen(MySocket, 5) == SOCKET_ERROR) // перевести гнездо в состояние ожидания

{

// cout<<endl<<"listen(...) error "<<WSAGetLastError()<<endl;(MySocket);0;

}(1) {= sizeof(sockaddr_in);= accept(MySocket, (sockaddr*)&MySocketAdress, &a); // принять соединение(newSocket == INVALID_SOCKET)

{

//cout<<endl<<"accept(...) error "<<WSAGetLastError()<<endl;(MySocket);0;

}

/*= sizeof(sockaddr_in);(getpeername(sw, (sockaddr*)&MySocketAdress, &a) != SOCKET_ERROR)

// попытаться получить адрес клиента

cout<<"accepted connection from "<<inet_ntoa(sa.sin_addr)<<endl;

*/

// запустить в отдельной нити функцию обслуживания клиента

if(!AfxBeginThread(ConnectHandler, (void*) newSocket))

{

//cout<<endl<<"_beginthread(...) error "<<errno<<endl;(MySocket);0;

}

}(MySocket);0;

}ConnectHandler( LPVOID pParam)

{s = (SOCKET) pParam;// гнездо, с которым будет вестись обменbuf[500], // буферы для данных[500], // буфер для шифрованного текста

pwd[21]; // парольlen[4];str;n, nFields;(pwd, password.operator LPCTSTR(), 20);

recv(s, len, sizeof len, 0); // прием данных от клиента= recv(s, encrypted, (int) len, 0); // прием данных от клиента

crypt(encrypted, buf, pwd, n);(n < 1) {(s); // закрытие гнезда0;

}{(IsBusy);= true;LipField;= pLipRec->Open(AFX_DB_USE_DEFAULT_TYPE, buf);= pLipRec->GetODBCFieldCount();(n != 0 || nFields > 0) {(s, (char*)&nFields, sizeof nFields, 0);(int i = 0; i < nFields; i++) {>GetODBCFieldInfo(i, LipField);= crypt(LipField.m_strName.operator LPCTSTR(),, pwd, LipField.m_strName.GetLength() + 1);(s, (char*)&n, sizeof n, 0);(s, encrypted, n, 0);

}>MoveFirst();(!pLipRec->IsEOF())

{(int i = 0; i < nFields; i++)

{>GetFieldValue(i, str);= crypt(str, encrypted, pwd, str.GetLength() + 1);(s, (char*)&n, sizeof n, 0);(s, encrypted, n, 0);

}>MoveNext( );(!pLipRec->IsEOF())[0] = 1;[0] = 0;(s, len, 1, 0);

}>Close();

}{= 0;(s, (char*)&nFields, sizeof nFields, 0);

}= false;(s, len, sizeof len, 0); // прием данных от клиента= recv(s, encrypted, (int) len, 0); // прием данных от клиента(encrypted, buf, pwd, n);

} while (n > 0);(s); // закрытие гнезда0;

}

#include "stdafx.h"

#include "crypt.h"

#include <string.h>

// функция преобразования строки пароля в гамму шифра

unsigned long gamma(char *pwd)

{buf[20];i;long flag;unsigned long g;(pwd) {(buf, 0x55, 20);// UUUUUUUUUUUUUUUUUUUU(buf, pwd, strlen(pwd));// passwordUUUUUUUUUUUU(i = 0, g = 0; i < 20; i++)// свертка пароля+= (unsigned long) (buf[i] << (i % 23));

}(i = 5; i > 0; i--) { // циклический сдвиг на 5 разрядов вправо

flag = g & 1;= g >> 1;(flag)

g |= 0x80000000;

}g; // возвратить значение гаммы

}

// шифрует открытый текст source по паролю pwd

// и записывает шифрованный текст в dest

// шифрование симметричноеcrypt(const char *source, char *dest, char *pwd, int len)

{, nBlocs;long *pSrc, *pDst, g;= (unsigned long *) source;= (unsigned long *) dest;

g = gamma(pwd);// получить гамму шифра= (len + 1) / 4 + 1; // сосчитать число 32-разрядных блоков(i = 0; i < nBlocs; i++, pDst++, pSrc++) // цикл гаммирования открытого

*pDst = *pSrc ^ gamma(0); // текста блоками по 32 бита[nBlocs * 4] = 0;// вставить завершающий символ 0nBlocs * 4 + 1;// возвратить число байт в зашифрованном тексте

}

Клиент

#include "stdafx.h"

#include "llip_client.h"

#include "llip_clientDoc.h"

#include "llip_clientView.h"

#include "PropDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILEchar THIS_FILE[] = __FILE__;

#endif_MESSAGE_MAP(CLlip_clientApp, CWinApp)

//{{AFX_MSG_MAP(CLlip_clientApp)_COMMAND(ID_APP_ABOUT, OnAppAbout)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

// Standard file based document commands_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)_MESSAGE_MAP()_clientApp::CLlip_clientApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}_clientApp theApp;CLlip_clientApp::InitInstance()

{short port; // порт сервераlong addr; // адрес сервераd(NULL);(d.DoModal() == IDOK) {= d.m_port;(m_pwd, d.m_pwd.operator LPCTSTR(), 20);= *((unsigned long*) d.m_addr);

}false;(!AfxSocketInit())

{(IDP_SOCKETS_INIT_FAILED);FALSE;

}

#ifdef _AFXDLLdControls();// Call this when using MFC in a shared DLL

#elsedControlsStatic();// Call this when linking to MFC statically

#endif(_T("Local AppWizard-Generated Applications"));(0); // Load standard INI file options (including MRU)* pDocTemplate;= new CSingleDocTemplate(_MAINFRAME,_CLASS(CLlip_clientDoc),_CLASS(CMainFrame), // main SDI frame window_CLASS(CLlip_clientView));(pDocTemplate);

// Parse command line for standard shell commands, DDE, file opencmdInfo;(cmdInfo);

// Dispatch commands specified on the command line(!ProcessShellCommand(cmdInfo))FALSE;

// The one and only window has been initialized, so show and update it._pMainWnd->ShowWindow(SW_SHOW);_pMainWnd->UpdateWindow();r;_pMainWnd->GetWindowRect(&r);.right = r.left + 500;.bottom = r.top + 380;_pMainWnd->MoveWindow(&r);

sockaddr_in sa;// структура данных гнезда

s = socket(AF_INET, SOCK_STREAM, 0);// создать гнездо(s == INVALID_SOCKET)

{(NULL, "Socket error.", "Ошибка", MB_OK);0;

}(addr == INADDR_NONE) // при ошибке

{(NULL, "Invalid IP address.", "Ошибка", MB_OK);(s);0;

}.sin_family = AF_INET;// заполнить структуру данных гнезда.sin_port = htons(port);.sin_addr.s_addr = addr;

// установить соединение:(connect(s, (sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR)

{(NULL, "Connect error.", "Ошибка", MB_OK);(s);0;

}TRUE;

}CAboutDlg : public CDialog

{:();

// Dialog Data

//{{AFX_DATA(CAboutDlg){ IDD = IDD_ABOUTBOX };

//}}AFX_DATA

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg):void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation:

//{{AFX_MSG(CAboutDlg)

// No message handlers

//}}AFX_MSG_MESSAGE_MAP()

};::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}CAboutDlg::DoDataExchange(CDataExchange* pDX)

{::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

}_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP_MESSAGE_MAP()

// App command to run the dialogCLlip_clientApp::OnAppAbout()

{aboutDlg;.DoModal();

}CLlip_clientApp::ExitInstance()

{(s); // закрыть гнездоCWinApp::ExitInstance();

}

Приложение Б

 

UML Диаграммы

Рисунок 1 (приложение Б) - диаграмма вариантов использования.

Рисунок 2(приложение Б) - диаграмма деятельности.


Рисунок 4(приложение Б) - диаграмма последовательности.

Приложение В

Электрическая структурная схема вычислительной сети


Рисунок 5 (приложение В) - электрическая структурная схема вычислительной сети

Похожие работы на - Информационно-вычислительная сеть на основе технологии клиент-сервер, предметная область: 'Диски'

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!