Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

отчет архитектура3

.docx
Скачиваний:
1
Добавлен:
31.03.2021
Размер:
70.02 Кб
Скачать

ФГБОУ ВО

Уфимский Государственный Авиационный Технический Университет

Кафедра ВМиК

Отчет по лабораторной работе №3

«Разработка клиент-серверного приложения с использованием базы данных»

по дисциплине

«Архитектура вычислительных систем и компьютерные сети»

Выполнили:

студенты группы МО-217

Ибрагимова Карина Базретдиновна

Шакиров Айдар Рушанович

Проверил:

Канд. техн. наук, доцент

Валеев Руслан Сагитович

Уфа 2019

Цель работы

Получение навыков разработки клиент-серверных приложений и создания баз данных.

Ход выполнения работы:

  1. Создание базы данных в СУБД MS Access.

  1. Создание серверного приложения. Оно должно принимать и передавать данные клиентским приложения. Реализована аутентификация пользователей, редактирование данных о них.

- Класс, инкапсулирующий работу с клиентскими TCP подключениями:

public class ClientObject

{

public string Id { get; private set; }

public NetworkStream Stream {get; private set;}

string userName;

TcpClient client;

ServerObject server; // объект сервера

public RichTextBox ChatBox;

UsersDataSet.UsersDataTable users;

public ClientObject(TcpClient tcpClient, ServerObject serverObject, RichTextBox chatBox)

{

Id = Guid.NewGuid().ToString();

client = tcpClient;

server = serverObject;

serverObject.AddConnection(this);

ChatBox = chatBox;

users = new UsersDataSet.UsersDataTable();

UsersTableAdapter usersTable = new UsersTableAdapter();

usersTable.Fill(users);

}

public void Process()

{

try

{

Stream = client.GetStream();

// получаем имя пользователя

string message = GetMessage();

userName = message.Split('%')[0];

var password = message.Split('%')[1];

//проверка логина и пароля

if (!users.Any(u => u.Nickname == userName && u.Password == password))

{

server.RemoveConnection(this.Id); //удалить из списка

Stream.Close();

client.Close();

}

message = userName + " вошел в чат\n";

// посылаем сообщение о входе в чат всем подключенным пользователям

server.BroadcastMessage(message, this.Id);

WriteInChat(message);

// в бесконечном цикле получаем сообщения от клиента

while (true)

{

try

{

message = GetMessage();

message = String.Format("{0}: {1}\n", userName, message);

WriteInChat(message);

server.BroadcastMessage(message, this.Id);

}

catch

{

message = String.Format("{0}: покинул чат\n", userName);

WriteInChat(message);

server.BroadcastMessage(message, this.Id);

break;

}

}

}

catch(Exception)

{

}

finally

{

// в случае выхода из цикла закрываем ресурсы

server.RemoveConnection(this.Id);

Close();

}

}

// чтение входящего сообщения и преобразование в строку

private string GetMessage()

{

byte[] data = new byte[64]; // буфер для получаемых данных

StringBuilder builder = new StringBuilder();

int bytes = 0;

do

{

bytes = Stream.Read(data, 0, data.Length);

builder.Append(Encoding.Unicode.GetString(data, 0, bytes));

}

while (Stream.DataAvailable);

return builder.ToString();

}

// закрытие подключения

public void Close()

{

if (Stream != null)

Stream.Close();

if (client != null)

client.Close();

}

public void WriteInChat(string message)

{

ChatBox.BeginInvoke((MethodInvoker)delegate

{

ChatBox.AppendText(message);

});

}

}

-Класс, инкапсулирующий работу с объектом для прослушивания TCP подключений:

public class ServerObject

{

TcpListener tcpListener; // сервер для прослушивания

List<ClientObject> clients = new List<ClientObject>(); // все подключения

RichTextBox ChatBox;

public ServerObject(RichTextBox chatBox)

{

ChatBox = chatBox;

}

public void AddConnection(ClientObject clientObject)

{

clients.Add(clientObject);

}

public void RemoveConnection(string id)

{

// получаем по id закрытое подключение

ClientObject client = clients.FirstOrDefault(c => c.Id == id);

// и удаляем его из списка подключений

if (client != null)

clients.Remove(client);

}

// прослушивание входящих подключений

public void Listen(IPAddress ip, int port)

{

try

{

tcpListener = new TcpListener(ip, port);

tcpListener.Start();

ChatBox.BeginInvoke((MethodInvoker)delegate

{

ChatBox.AppendText("Сервер запущен. \n");

});

while (true)

{

TcpClient tcpClient = tcpListener.AcceptTcpClient();

ClientObject clientObject = new ClientObject(tcpClient, this, ChatBox);

Task.Run(()=>

{

clientObject.Process();

});

}

}

catch (Exception e)

{

MessageBox.Show("Listen() " + e.Message);

Disconnect();

}

}

//отправка всем

public void BroadcastMessage(string message, string id)

{

byte[] data = Encoding.Unicode.GetBytes(message);

for (int i = 0; i < clients.Count; i++)

{

if (clients[i].Id != id) // если id клиента не равно id отправляющего

{

clients[i].Stream.Write(data, 0, data.Length); //передача данных

}

}

}

public void Disconnect()

{

tcpListener.Stop(); //остановка сервера

for (int i = 0; i < clients.Count; i++)

{

clients[i].Close(); //отключение клиента

}

Environment.Exit(0);

}

}

-Работа основной части приложения

private void StartBtn_Click(object sender, EventArgs e)

{

int port = Convert.ToInt32(PortText.Text);

try

{

server = new ServerObject(ChatBox);

Task.Run(()=> //новый поток

{

server.Listen(IPAddress.Parse(IPText.Text), port);

});

}

catch (Exception ex)

{

server.Disconnect();

MessageBox.Show(ex.Message);

}

}

private void SendBtn_Click(object sender, EventArgs e)

{

string message = "server: " + MessageText.Text + "\n";

ChatBox.AppendText(message);

server.BroadcastMessage(message, "0");

}

  1. Разработка клиентского приложения. Данное приложение передает данные серверному. Также получает данные, отправленные широковещательной рассылкой.

string userName;

string password;

TcpClient client;

NetworkStream stream;

private void ConnectBtn_Click(object sender, EventArgs e)

{

userName = NicknameText.Text;

password = PasswordText.Text;

client = new TcpClient();

try

{

client.Connect(IPText.Text, Convert.ToInt32(PortText.Text)); //подключение клиента

stream = client.GetStream(); // получаем поток

string message = userName + "%" + password;

byte[] data = Encoding.Unicode.GetBytes(message);

stream.Write(data, 0, data.Length);

// запускаем новый поток для получения данных

Task.Run(() =>

{

ReceiveMessage();

});

ChatBox.AppendText($"Добро пожаловать, {userName} \n");

}

catch (Exception ex)

{

MessageBox.Show("ConnectBtn_Click() " + ex.Message);

}

}

void SendMessage(string message)

{

try

{

byte[] data = Encoding.Unicode.GetBytes(message);

stream.Write(data, 0, data.Length);

ChatBox.AppendText("Вы: " + message + "\n");

}

catch (Exception)

{

}

}

void ReceiveMessage()

{

while (true)

{

try

{

byte[] data = new byte[64]; // буфер для получаемых данных

StringBuilder builder = new StringBuilder();

int bytes = 0;

do

{

bytes = stream.Read(data, 0, data.Length);

builder.Append(Encoding.Unicode.GetString(data, 0, bytes));

}

while (stream.DataAvailable);

string message = builder.ToString();

if (string.IsNullOrWhiteSpace(message)) //костыль, чтобы понять, что подключение больше не работает

SendMessage("err");

ChatBox.BeginInvoke((MethodInvoker)delegate

{

ChatBox.AppendText(message);//вывод сообщения

});

Thread.Sleep(105);

}

catch (Exception)

{

ChatBox.BeginInvoke((MethodInvoker)delegate

{

ChatBox.AppendText("Подключение прервано" + "\n");//вывод сообщения

});

Disconnect();

return;

}

}

}

void Disconnect()

{

if (stream != null)

stream.Close();//отключение потока

if (client != null)

client.Close();//отключение клиента

//Environment.Exit(0); //завершение процесса

}

private void SendBtn_Click(object sender, EventArgs e)

{

SendMessage(MessageText.Text);

}

Интерфейс программы:

Серверное приложение:

Клиентское приложение:

Заключение:

В ходе лабораторной работы получены навыки разработки клиент-серверных приложений и создания баз данных.

Соседние файлы в предмете Архитектура ЭВМ