Проектирование и разработка программы ЧАТ для локальной сети - Программирование, компьютеры и кибернетика курсовая работа

Главная
Программирование, компьютеры и кибернетика
Проектирование и разработка программы ЧАТ для локальной сети
История возникновения чата. Виды программной реализации чатов. Описание приложения TCP/IP, построенного на клиент-серверной архитектуре. Особенности создания многопользовательского чата (Multy-user on-line). Листинг программного продукта онлайн общения.
посмотреть текст работы
скачать работу можно здесь
полная информация о работе
весь список подобных работ
Нужна помощь с учёбой? Наши эксперты готовы помочь!
Нажимая на кнопку, вы соглашаетесь с
политикой обработки персональных данных
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
АВТОНОМНАЯ НЕКОМЕРЧЕСКАЯ ОБРАЗОВАТЕЛЬНАЯ ОРГАНИЗАЦИЯ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ВОРОНЕЖСКИЙ ЭКОНОМИКО-ПРАВОВОЙ ИНСТИТУТ
ФИЛИАЛ г. СТАРЫЙ ОСКОЛ БЕЛГОРОДСКОЙ ОБЛАСТИ
КАФЕДРА «ГУМАНИТАРНЫХ И ЕСТЕСТВЕННОНАУЧНЫХ ДИСЦИПЛИН»
По дисциплине: Проектирование информационных систем
Проектирование и разработка программы ЧАТ для локальной сети
Глава I. История возникновения чата
Глава II. Создание многопользовательского чата
Компоненты из стандартного пакета Delphi ServerSocket и ClientSocket не всегда могут быть отображены в палитре Internet, и их нужно загрузить следующим образом: выбрать меню: Component - Install Packages… - Add., далее нужно указать файл …\bin\dclsockets70.bpl.
Как правило, разработка любой программы начинается с определения задач, которые она должна выполнять, и определения уже на этом этапе нужных компонентов. Программа представляет собой чат для нескольких пользователей, каждый из которых может быть как сервером, так и клиентом, значит, кидаем в форму компоненты ServerSocket и ClientSocket. Важным параметром для всех является порт. Только при одинаковом значении свойства Port, связь между ними установится. Кинем в форму компонент Edit, чтобы оперативно изменять порт, назовем его PortEdit. Для соединения с сервером необходимо указывать IP сервера или его имя, поэтому кинем еще один Edit, назовем его HostEdit. Так же нам понадобятся еще два Edit'а для указания ника и ввода текста сообщения, назовем их NikEdit и TextEdit, соответственно. Текст принимаемых и отправляемых сообщений будет отображаться в Memo, кинем его в форму и назовем ChatMemo. Установим сразу вертикальную полосу прокрутки: ScrollBars = ssVertical, и свойство ReadOnly = True. Добавим клавиши управления Button: ServerBtn - для создания/закрытия сервера, ClientBtn - для подключения/отключения клиента к серверу, SendBtn - для отправки сообщений. Изменим Caption этих клавиш на “Создать сервер”, “Подключиться” и “Отправить”, соответственно. UserListView предназначен для вывода списка пользователей, который будет динамически обновляться при подключении или отключении пользователей. Сам компонент ListView настраивается как табличный отчет: свойство ViewStyle = vsReport (стиль таблицы), свойство ShowColumnHeaders = False (не показывать имена столбцов), свойство ReadOnly = True (только отображение), свойство SmallImages = ImageList (массив с иконками). Двойным кликом на компоненте ListView выводится редактор Editing UserListView.Columns. Добавляется один столбец (порядковый номер -0). В ImageList через Add закидываются иконки, в нашем случае две, с изображением силуэта пользователя: в белом - пометка сервера, в красном - пометка клиента.
Теперь разберем принцип работы сервера . Традиционно в ServerSocket для приема клиентских пакетов используется OnClientRead, но данный способ не очень удобен, ведь для идентификации пакета (кто прислал) потребуется повозиться со структурой “прием\ответ” и решить каким образом будет происходить синхронизация. Гораздо проще и эффективнее использовать цикл по числу пользователей, в котором ведется “прослушивание” всех каналов и обработка пакета, если он пришел на конкретный канал, закрепленный за конкретным пользователем. Процедура “прослушивания” каналов выполняется в теле таймера, интервал (Interval) работы которого можно изменять по необходимости (для чата нормально 500 мс, для игр нужно существенно меньше). Вот так выглядит общая структура процедуры опроса:
procedure TForm1.Timer1Timer(Sender: TObject);
begin // условие на наличие установленных каналов
if ServerSocket.Socket.ActiveConnections<>0 then begin // цикл по существующим каналам
for i:=1 to ServerSocket.Socket.ActiveConnections do begin // сохраним пакет (если ничего не прислали, по пакет пустой)
text:=ServerSocket.Socket.Connections.ReceiveText(); // условие, что пакет не пуст if text<>” then begin {тут обработка строки, выделение составляющих кода команд (com) и пр.} // определение команд case com of код: begin {процедура} end; код: begin {процедура} end; ……………………………………. end; end; end; end; // разрешение на выполнение процедур обновления if UpdDo=True then begin {процедуры} // блокируем разрешение UpdDo:=False; end; end;
Если заметили, что цикл начинается с единицы, а в инициализации канала странное выражение (вместо логичного начала с нуля и инициализации), то такое решение существенным образом облегчает организацию ряда процедур. Например, в списке пользователей, сервер числится под номером “0”, а клиенты - начиная с “1”. Так же удобно совмещать количество каналов (ServerSocket.Socket.ActiveConnections) с процедурами определения активности пользователей. Последнее условие в теле таймера необходимо для задержки выполнения некоторых процедур обновления. Эти процедуры должны выполняться в самом конце “прослушивания” открытых каналов, и не всегда (если будет команда). Данный алгоритм применим практически к любого рода соединениям Клиент-сервер, в том числе и для игр.
Перейдем непосредственно к приложению чата и его процедурам. Проверок на корректность ввода значений в поля не будет. Создадим новый тип, для использования массива объектов, так гораздо удобнее:
Type TUserList = object Status: Byte; // 1 - сервер, 2 - клиент Rec: Boolean; // отметка записи пользователя в список Name: String; // имя (ник) Image: Byte; // индекс иконки end;
Вот переменные, которые понадобятся в программе:
var Form1: TForm1; i, j, com, ContList: Byte; len, pos, x: Word; text, StrUserList: String; UpdDo: Boolean; Buf: array[0..3] of Byte; UserMas: array[0..255] of TUserList; //массив объектов UItems: TListItem;
procedure TForm1.FormCreate(Sender: TObject); begin // заголовок формы Caption:='Многопользовательский чат'; Application.Title:=Caption; // предложенное значения порта PortEdit.Text:=' Порт сервера'; // адрес при проверке программы на одном ПК ("сам на себя") HostEdit.Text:=' Адрес сервера '; // введем ник по-умолчанию, остальные поля просто очистим NikEdit.Text:='Ананим'; TextEdit.Clear; ChatMemo.Lines.Clear; end;
Процедура “ прослушивания ” открытых каналов сервером , выглядит так:procedure TForm1.ServerTimerTimer(Sender: TObject); begin // условие на наличие установленных каналов if ServerSocket.Socket.ActiveConnections<>0 then begin // цикл по существующим каналам for i:=1 to ServerSocket.Socket.ActiveConnections do begin // сохраним пакет (если ничего не прислали, по пакет пустой)
text:=ServerSocket.Socket.Connections.ReceiveText(); // условие, что пакет не пуст if text<>” then begin // получим код команды, длину строки com:=StrToInt(Copy(text,1,1)); len:=Length(text)-1; // определение команд case com of // код приема сообщения 0: begin // добавим в ChatMemo сообщение клиента ChatMemo.Lines.Add(Copy(text,2,len)); // разошлем сообщение пользователям (кроме того, кто прислал) for j:=0 to ServerSocket.Socket.ActiveConnections-1 do begin if (j+1)<>i then ServerSocket.Socket.Connections[j].SendText('0?+Copy(text,2,len)); end; end; // код приема ника клиента 1: begin // запишем в массив полученный ник UserMas.Name:=Copy(text,2,len); // отметим, что пользователь записан в список UserMas.Rec:=True; // обновляем список UpdateUserList; end; end; end; end; end; // разрешение на выполнение процедур обновления if UpdDo=True then begin // обновляем массив пользователей UpdateUserMas; // обновляем список пользователей UpdateUserList; // блокируем разрешение UpdDo:=False; end; end;
Перевод программы в режим сервера осуществляется клавишей “Создать сервер” (ServerBtn). Вот так выглядит процедура на нажатие клавиши ServerBtn (OnClick):
procedure TForm1.ServerBtnClick(Sender: TObject); begin if ServerBtn.Tag=0 then begin // клавишу ClientBtn и поля HostEdit, PortEdit, NikEdit заблокируем ClientBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; NikEdit.Enabled:=False; // запишем указанный порт в ServerSocket ServerSocket.Port:=StrToInt(PortEdit.Text); // запускаем сервер ServerSocket.Active:=True; // добавим в ChatMemo сообщение с временем создания ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан.'); // изменяем тэг ServerBtn.Tag:=1; // меняем надпись клавиши ServerBtn.Caption:='Закрыть сервер'; // включаем таймер сервера ServerTimer.Enabled:=True; // вписываем параметры сервера UserMas[0].Status:=1; UserMas[0].Rec:=True; UserMas[0].Name:=NikEdit.Text; UserMas[0].Image:=1; // разрешаем обновление UpdDo:=True; end else begin // выключаем таймер сервера ServerTimer.Enabled:=False; // стираем параметры сервера UserMas[0].Status:=0; UserMas[0].Rec:=False; UserMas[0].Name:='Неизвестный'; UserMas[0].Image:=0; // разрешаем обновление UpdDo:=True; // очищаем список клиентов UserListView.Items.Clear; // клавишу ClientBtn и поля HostEdit, PortEdit, NikEdit разблокируем ClientBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; NikEdit.Enabled:=True; // закрываем сервер ServerSocket.Active:=False; // выводим сообщение в ChatMemo ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер закрыт.'); // возвращаем тэгу исходное значение ServerBtn.Tag:=0; // возвращаем исходную надпись клавиши ServerBtn.Caption:='Создать сервер'; end; end;
Далее идут события, которые должны происходить при определенном состоянии ServerSocket'а. Напишем процедуру, когда клиент подсоединился к серверу (OnClientConnect):
procedure TForm1.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение с временем подключения клиента ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.'); // разрешаем обновление UpdDo:=True; end;
Напишем процедуру, когда клиент отключается (OnClientDisconnect):
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение с временем отключения клиента ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.'); // разрешаем обновление UpdDo:=True; end;
Отправка сообщений . Она осуществляется нажатием клавиши “Отправить” (SendBtn), но необходима проверка режима программы сервер или клиент. Напишем ее процедуру (OnClick):
procedure TForm1.SendBtnClick(Sender: TObject); begin // проверка, в каком режиме находится программа if ServerSocket.Active=True then // отправляем сообщение с сервера всем пользователям for i:=0 to ServerSocket.Socket.ActiveConnections-1 do ServerSocket.Socket.Connections.SendText('0['+TimeToStr(Time)+'] `+NikEdit.Text+': `+TextEdit.Text) else // отправляем сообщение с клиента ClientSocket.Socket.SendText('0['+TimeToStr(Time)+'] `+NikEdit.Text+': `+TextEdit.Text); // отобразим сообщение в ChatMemo ChatMemo.Lines.Add('['+TimeToStr(Time)+'] `+NikEdit.Text+': `+TextEdit.Text); // очищаем TextEdit TextEdit.Clear; end;
Режим клиента . При нажатии клавиши “Подключиться” (ClientBtn), блокируется ServerBtn и активируется ClientSocket. Вот процедура ClientBtn (OnClick):
procedure TForm1.ClientBtnClick(Sender: TObject); begin if ClientBtn.Tag=0 then begin // клавишу ServerBtn и поля HostEdit, PortEdit заблокируем ServerBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; // запишем указанный порт в ClientSocket ClientSocket.Port:=StrToInt(PortEdit.Text); // запишем хост и адрес (одно значение HostEdit в оба) ClientSocket.Host:=HostEdit.Text; ClientSocket.Address:=HostEdit.Text; // запускаем клиента ClientSocket.Active:=True; // изменяем тэг ClientBtn.Tag:=1; // меняем надпись клавиши ClientBtn.Caption:='Отключиться'; end else begin // клавишу ServerBtn и поля HostEdit, PortEdit разблокируем ServerBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; // закрываем клиента ClientSocket.Active:=False; // очищаем список клиентов UserListView.Items.Clear; // выводим сообщение в ChatMemo ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сессия закрыта.'); // возвращаем тэгу исходное значение ClientBtn.Tag:=0; // возвращаем исходную надпись клавиши ClientBtn.Caption:='Подключиться'; end; end;
Процедуры на OnConnect, OnDisconnect, OnRead клиента ClientSocket. Сначала на чтение сообщения с сервера (OnRead):
procedure TForm1.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); begin // получим текст, код комманды, длину строки text:=Socket.ReceiveText(); com:=StrToInt(Copy(text,1,1)); len:=Length(text)-1; // определение комманд case com of // добавим в ChatMemo сообщение с сервера 0: ChatMemo.Lines.Add(Copy(text,2,len)); // отошлем свой ник на сервер 1: ClientSocket.Socket.SendText('1'+NikEdit.Text); // примем строку списка пользователей 2: begin // очищаем список клиентов UserListView.Items.Clear; // добавим ключ конца строки (т.к. вырезка символов с задержкой) text:=text+Chr(152); // укажем начальный символ pos:=2; // обнулим счетчик символов x:=0; // пробегаем по длине строки списка for j:=2 to len+1 do begin // записываем в счетчик сдвиг x:=x+1; // если найден ключ (отделение ников в строке) if Copy(text,j,1)=Chr(152) then begin // добавим в UserListView строку UItems:=UserListView.Items.Add; UItems.Caption:=Copy(text,pos,x-1); // укажем соответствующую иконку пользователя if pos>2 then UItems.ImageIndex:=0 else UItems.ImageIndex:=1; // изменим текущую позицию в строке списка pos:=j+1; // обнулим счетчик символов x:=0; end; end; end; end; end;
Дальше обычное добавление в ChatMemo определенного сообщения:
procedure TForm1.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение о соединении с сервером ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключение к серверу.'); end;
procedure TForm1.ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение о потере связи ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер не найден.'); end;
Хранителем информации о пользователях у нас выступает массив, процедура его заполнения и обновления выглядит так:
procedure TForm1.UpdateUserMas; begin // очищаем массив с информацией for i:=1 to 255 do begin UserMas.Status:=0; UserMas.Rec:=False; UserMas.Name:='Неизвестный'; UserMas.Image:=0; end; // заполняем данные пользователей if ServerSocket.Socket.ActiveConnections<>0 then begin for i:=1 to ServerSocket.Socket.ActiveConnections do begin UserMas.Status:=2; UserMas.Name:='Неизвестный'; UserMas.Image:=0; // запрашиваем имя (ник) пользователя по его каналу (код команды - 1) ServerSocket.Socket.Connections.SendText('1?); end; end; end;
Список UserListView обновляется в следующей процедуре:
procedure TForm1.UpdateUserList; begin // очищаем список клиентов UserListView.Items.Clear; // очищаем переменную StrUserList:=''; // обнуляем пометку записи ContList:=0; // пробегаем по диапазону каналов for i:=0 to 255 do begin // если запись не пустая if UserMas.Status<>0 then begin // добавим в UserListView строку UItems:=UserListView.Items.Add; UItems.Caption:=UserMas.Name; UItems.ImageIndex:=UserMas.Image; // если пользователь не записан if UserMas.Rec=False then ContList:=1; // составляем строку пользователей StrUserList:=StrUserList+UserMas.Name+Chr(152); end; end; // если все пользователи отметились, и есть хоть один канал if (ContList=0) and (ServerSocket.Socket.ActiveConnections<>0) then begin // пробегаем по всем открытым каналам for i:=0 to ServerSocket.Socket.ActiveConnections-1 do begin // отправим строку списка пользователей (код команды - 2) ServerSocket.Socket.Connections.SendText('2?+StrUserList); end; end; end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls, ImgList, ComCtrls, jpeg;
procedure FormCreate(Sender: TObject);
procedure ServerBtnClick(Sender: TObject);
procedure ClientBtnClick(Sender: TObject);
procedure ServerSocketClientConnect(Sender: TObject;
procedure ServerSocketClientDisconnect(Sender: TObject;
procedure SendBtnClick(Sender: TObject);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocketDisconnect(Sender: TObject;
procedure ClientSocketConnect(Sender: TObject;
procedure ServerTimerTimer(Sender: TObject);
procedure TextEditKeyDown(Sender: TObject; var Key: Word;
UserMas: array[0..255] of TUserList;
procedure TForm1.FormCreate(Sender: TObject);
Caption:='Многопользовательский чат';
UItems.ImageIndex:=UserMas[i].Image;
If UserMas[i].Rec=False then ContList:=1;
StrUserList:=StrUserList+UserMas[i].Name+Chr(152);
If (ContList=0) And (ServerSocket.Socket.ActiveConnections<>0) then
For i:=0 to ServerSocket.Socket.ActiveConnections-1 do
ServerSocket.Socket.Connections[i].SendText('2'+StrUserList);
If ServerSocket.Socket.ActiveConnections<>0 then
For i:=1 to ServerSocket.Socket.ActiveConnections do
ServerSocket.Socket.Connections[i-1].SendText('1');
procedure TForm1.ServerBtnClick(Sender: TObject);
ServerSocket.Port:=StrToInt(PortEdit.Text);
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан.');
ServerBtn.Caption:='Закрыть сервер';
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер закрыт.');
ServerBtn.Caption:='Создать сервер';
procedure TForm1.ClientBtnClick(Sender: TObject);
ClientSocket.Port:=StrToInt(PortEdit.Text);
ClientSocket.Address:=HostEdit.Text;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сессия закрыта.');
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.');
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.');
procedure TForm1.SendBtnClick(Sender: TObject);
For i:=0 to ServerSocket.Socket.ActiveConnections-1 do
ServerSocket.Socket.Connections[i].SendText('0['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text)
ClientSocket.Socket.SendText('0['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text);
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text);
procedure TForm1.ClientSocketRead(Sender: TObject;
0: ChatMemo.Lines.Add(Copy(text,2,len));
1: ClientSocket.Socket.SendText('1'+NikEdit.Text);
UItems.Caption:=Copy(text,pos,x-1);
If pos>2 then UItems.ImageIndex:=0 else UItems.ImageIndex:=1;
procedure TForm1.ClientSocketConnect(Sender: TObject;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключение к серверу.');
procedure TForm1.ClientSocketDisconnect(Sender: TObject;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер не найден.');
procedure TForm1.ServerTimerTimer(Sender: TObject);
If ServerSocket.Socket.ActiveConnections<>0 then
For i:=1 to ServerSocket.Socket.ActiveConnections do
text:=ServerSocket.Socket.Connections[i-1].ReceiveText();
ChatMemo.Lines.Add(Copy(text,2,len));
For j:=0 to ServerSocket.Socket.ActiveConnections-1 do
If (j+1)<>i then ServerSocket.Socket.Connections[j].SendText('0'+Copy(text,2,len));
procedure TForm1.TextEditKeyDown(Sender: TObject; var Key: Word;
If Key=VK_RETURN then SendBtn.Click;
В моей курсовой работе я достиг, поставленных перед собою целей реализовав программный продукт онлайн общения - чат. Данный проект может быть развит в перспективе до более высокого уровня, добавив некоторые новые функциональных возможностей.
В данный момент, в связи с бурным развитием WEB технологий, нет смысла создавать собственную программу чата. Так как в более удобно взять уже готовый, полностью завершенный чат.
При подключение к серверу (у сервера):
При подключении к серверу (у клиента):
Отправка сообщений (у сервера и клиента):
Характеристика разновидностей программной реализации чатов. Разработка программы клиент-серверного чата с возможность общения в локальной сети нескольких человек одновременно. Протокол взаимодействия клиента и сервера. Порядок работы с программой. курсовая работа [530,7 K], добавлен 25.04.2015
Обоснование необходимости создания приложения для общения в Интернете, информационный анализ его структуры. Логическое проектирование чата. Выбор программной платформы, аппаратных средств и среды разработки. Интерфейс программы и руководство пользователя. курсовая работа [287,7 K], добавлен 19.06.2013
Требования, предъявленные к полноценному локальному чату. Протокол передачи данных TCP. Описание программы сервера. Этапы разработки программного продукта. Функция приема сообщений от сервера. Принятие и отправка сообщений всем пользователям чата. курсовая работа [447,0 K], добавлен 21.01.2016
Особенности настройки корпоративной сети предприятия. Разработка приложения, обеспечивающего эффективную работу клиент-серверной сети железнодорожной кассы. Защита от несанкционированного доступа, специфика шифрования паролей и ряд других средств защиты. курсовая работа [5,9 M], добавлен 30.01.2014
Общая характеристика и функциональное назначение проектируемого программного обеспечения, требования к нему. Разработка и описание интерфейса клиентской и серверной части. Описание алгоритма и программной реализации приложения. Схема базы данных. курсовая работа [35,4 K], добавлен 12.05.2013
Разработка текстового автоответчика для программы Skype, который будет выдавать определенные данные на основе отправляемых пользователем сообщений. Особенности программного обеспечения для чатов. Схема взаимодействия пользователя и интерфейса чата. курсовая работа [1,0 M], добавлен 08.06.2017
Проектирование и разработка базы данных в РСУБД Firebird. Последовательность создания приложения, основанного на клиент-серверной технологии и работающего в операционной системе Windows. Хранимые процедуры и триггеры. Доступ к сети и транзакции. курсовая работа [2,6 M], добавлен 27.07.2013
Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д. PPT, PPTX и PDF-файлы представлены только в архивах. Рекомендуем скачать работу .
© 2000 — 2021
Проектирование и разработка программы ЧАТ для локальной сети курсовая работа. Программирование, компьютеры и кибернетика.
Уголовная ответственность за правонарушения в сфере экономической деятельности
Контрольная работа по теме Открытое акционерное общество. Акции и их виды
Учебное пособие: Механика методические указания по выполнению курсовой работы по разделу "Кинематика" для студентов очной и заочной форм обучения специальности 200101 «Приборостроение» Часть 2 Санкт-Петербург 2010
Сертификация услуг и сертификация продукции
Реферат На Тему Гёте
Сочинение По Картине Попова Снег
Почему Мне Нравится Дубровский Сочинение 6 Класс
Какого Человека Можно Назвать Сильной Личностью Сочинение
Реферат Бронхиальная Астма Понятие Классификация Клиника Принципы Лечения
Социально Культурная Сфера Курсовая
Курсовая работа по теме Жилое здание на 8 квартир в городе Райчихинске
Контрольная работа по теме Характеристика русского языка
Виды описания систем
Курсовая работа по теме Кредитные операции банков на современном этапе
Сочинение О Чехове Как О Писателе
Онр Курсовые Работы
Уникальность Реферата Онлайн
Отчет По Практике На Тему Характеристика Работы Всех Функциональных Подразделений Ракитянского Районного Потребительского Общества
Магистерская диссертация по теме Речевая агрессия в печатных средствах массовой информации
Реферат: Фонсека Амадор, Карлос
Виртуальное моделирование автомобилей в программе 3ds max, их анимация и визуализация - Программирование, компьютеры и кибернетика статья
Розничная купля-продажа и защита прав потребителей - Государство и право курсовая работа
Іспанський етнополітичний тероризм - История и исторические личности реферат