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

Лекции / РАЗРАБОТКА ПРИЛОЖЕНИЯ С КЛИЕНТ-СЕРВЕРНОЙ АРХИТЕКТУРОЙ

.pdf
Скачиваний:
63
Добавлен:
08.05.2022
Размер:
902.39 Кб
Скачать

 

 

95

 

m = SerializeAndDeserialize.Serialize(cm);

Сериализованное значение объекта cm

 

 

 

 

присваиваем переменной m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

96

 

responseData = m.Data;

 

 

 

В массив responseData копируем содержимое

 

 

 

 

 

 

 

массива Data объекта m

 

 

 

 

 

 

 

 

 

 

 

 

 

 

97

 

Stream.Write(responseData, 0,

 

 

Отправляем массив байтов responseData

 

 

 

 

 

 

responseData.Length);

 

 

 

клиенту

 

 

 

98

 

label:

 

 

 

 

 

 

 

 

99

 

responseData = null;

 

 

 

Обнуление массива responseData

 

 

 

100

}}}}}

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

прослушивание в основном классе программы.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Листинг 24.12 – Запуск работы сервера

 

 

 

 

 

 

 

 

 

 

1

 

public partial class Form1 : Form

 

 

 

 

 

2

 

{

 

 

 

 

 

 

 

 

3

 

ServerObject server;

 

 

 

 

Создание объекта сервера

 

 

4

 

static Thread listenThread;

 

 

 

Объявление потока для прослушивания запросов

 

 

5

 

public Form1()

 

 

 

 

 

 

 

6

 

{

 

 

 

 

 

 

 

 

7

 

InitializeComponent();

 

 

 

 

 

 

8

 

server = new ServerObject();

 

 

 

 

 

 

9

 

listenThread

=

new

Thread(new

 

Создание потока и прикрепление к нему метода

 

 

 

ThreadStart(server.Listen));

 

 

 

прослушивания Listen класса ServerObject

 

 

10

 

listenThread.Start();}}

 

 

 

Запуск потока listenThread

 

21

4. Клиентская часть приложения

Рассмотрим реализацию клиентской части приложения.

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

Начнем с изменения процесса регистрации. При регистрации данные, введенные в текстовые поля пользователем, передаются как инициализирующие значения свойств объекта класса User и Student (если выбрана регистрация студента) или Professor

(если выбрана регистрация преподавателя). Далее созданные объекты сериализуются и отправляются для дальнейшей обработки серверу.

Схема передачи и приема сериализованных объектов от клиента серверу при регистрации студента представлена на рисунке 24.7.

Рисунок 24.7 – Схема передачи сериализованных объектов

Модифицированная версия процесса регистрации представлена в листинге 24.13.

 

 

 

Листинг 24.13 Регистрация пользователя

 

 

 

 

 

 

1

public partial class FormReg : Form

Класс формы регистрации

 

 

2

{

 

 

 

3

private Form1 Form1;

Экземпляр класса формы авторизации

 

 

4

private byte[] imageBytes;

Массив байтов для хранения фотографии

 

 

пользователя

 

 

 

 

 

 

 

 

Объект TCP-клиента. В конструктор класса

 

 

5

private TcpClient client = new

TcpClient передается физический IP-адрес

 

 

TcpClient("127.0.0.1", 8888);

("127.0.0.1") расположения сервера и номер порта

 

 

 

 

 

 

 

(8888), по которому происходит подключение.

 

 

6

private Byte[] data;

Массив байтов для хранения данных, передаваемых от

 

 

клиента к серверу

 

 

 

 

 

 

7

private NetworkStream stream;

Поток, используемый для взаимодействия с сервером

 

 

8

private MyLib.Message m1, m2, m;

Экземпляры класса Message из библиотеки MyLib,

 

 

9

private ComplexMessage cm = new

 

 

созданной на предыдущем этапе

 

 

ComplexMessage();

 

 

 

 

 

 

10

public FormReg(Form1 form1)

Конструктор класса формы регистрации

 

 

11

{

 

 

 

12

InitializeComponent();

 

 

 

13

this.Form1 = form1;

Инициализация свойства, определенного в строке 3

 

 

14

this.stream = client.GetStream();

Инициализация потока, определенного в строке 7

 

 

15

}

 

 

 

 

 

Метод, инициализирующий элементы отправляемого

 

 

16

private void InitComponentMessage(object

серверу пакета данных. Здесь first – первый элемент

 

 

first, object second, int status)

пакета, second – второй элемент пакета, status

 

 

 

 

номер статуса, определяющий тип запроса.

 

 

17

{

 

 

 

18

this.m1 =

Инициализация объекта m1 значением, полученным

 

 

SerializeAndDeserialize.Serialize(first);

после сериализации объекта first

 

 

19

this.m2 =

Инициализация объекта m2 значением, полученным

 

 

SerializeAndDeserialize.Serialize(second);

после сериализации объекта second

 

 

20

cm.First = m1;

Присваивание свойству First объекта cm ссылки на

 

 

объект m1

 

 

 

 

 

 

21

cm.Second = m2;

Присваивание свойству Second объекта cm ссылки на

 

 

объект m2

 

 

 

 

 

 

22

cm.NumberStatus = status;

Инициализация статуса запроса

 

 

23

m = SerializeAndDeserialize.Serialize(cm);

Инициализация объекта m значением, полученным

 

 

после сериализации объекта cm

 

 

 

 

 

 

24

this.data = m.Data;

Инициализация массива байтов data ссылкой на

 

 

свойство Data объекта m

 

 

 

 

 

 

25

}

 

 

 

26

private void buttonReg_Click(object

Метод обработчик нажатия на кнопку

 

 

sender, EventArgs e)

«Зарегистрироваться»

 

 

27

{

 

 

 

28

if (comboBoxRole.SelectedItem.ToString()

Если при заполнении текстовых полей в качестве роли

 

 

== "Студент")

в comboBoxRole указан «Студент»

 

29{

Student student = new Student() { Name = textBoxFIO.Text, NumberGroup =

 

 

 

int.Parse(textBoxNumGroup.Text),

 

Создается объект student и инициализируются все

 

 

30

 

PersonalData =

 

его свойства согласно значениям, введенным в

 

 

 

 

richTextBoxPersonalData.Text, Photo =

 

соответствующие текстовые поля.

 

 

 

 

this.imageBytes, Specialty = "Программист"

 

 

 

 

 

};

 

 

 

 

 

 

User user = new User() { Student =

 

Создается объект user и инициализируются все его

 

 

 

 

student, Login = textBoxLogin.Text,

 

 

 

31

 

 

свойства согласно значениям, введенным в

 

 

 

Password = textBoxPassword.Text, Role =

 

 

 

 

 

(string)comboBoxRole.SelectedItem };

 

соответствующие текстовые поля.

 

 

 

 

 

 

 

 

 

24

 

 

 

Вызов метода InitComponentMessage и передача в

32 this.InitComponentMessage(student,0); user, него в качестве параметра first – объекта student, second – объекта user, status – цифры 0.

33}

else if

34(comboBoxRole.SelectedItem.ToString() == "Преподаватель")

35{

Professor professor = new Professor() { Name = textBoxFIO.Text, Position =

36textBoxNumGroup.Text, PersonalData = richTextBoxPersonalData.Text, Photo = this.imageBytes };

User user = new User() { Professor = professor, Login = textBoxLogin.Text,

37Password = textBoxPassword.Text, Role = (string)comboBoxRole.SelectedItem };

38this.InitComponentMessage(professor,0); user,

39}

Если при заполнении текстовых полей в качестве роли в comboBoxRole указан «Преподаватель»

Создается объект professor и инициализируются все его свойства согласно значениям, введенным в

соответствующие текстовые поля.

Создается объект user и инициализируются все его свойства согласно значениям, введенным в

соответствующие текстовые поля.

Вызов метода InitComponentMessage и передача в него в качестве параметра first – объекта student, second – объекта user, status – цифры 0.

 

40

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

Отправляем массив байтов data серверу

41

stream.Flush();

Очистка содержимого потока stream

42}

43

44}

25

26

При авторизации данные, введенные в текстовые поля пользователем, передаются серверу для дальнейшего сравнения на равенство со значениями свойства логина и пароля пользователя из базы данных. Далее, если нашлось совпадение логина и пароля в базе данных, в сервере создается объект User, он сериализуются и отправляются для дальнейшей обработки клиенту.

Модифицированная версия процесса авторизации представлена в листинге 24.14.

 

Листинг 24.14 – Класс формы авторизации

 

 

 

1

public partial class Form1 : Form

 

2

{

 

3

FormReg FormReg;

 

4

FormStudentAccount FormStudentAccount;

 

5

FormReference FormReference;

 

6

FormProfessorAccount FormProfessorAccount;

 

7

TcpClient client = new TcpClient("127.0.0.1", 8888);

 

8

Byte[] data;

 

9

NetworkStream stream;

 

10

MyLib.Message m, m1, m2;

 

11

ComplexMessage cm = new ComplexMessage();

 

12

public Form1()

 

13

{

 

14

InitializeComponent();

 

15

this.stream = client.GetStream();

 

16

}

 

17

private void buttonAuth_Click(object sender, EventArgs e)

 

18

{

 

 

this.m1 =

 

19

SerializeAndDeserialize.Serialize(textBoxLogin.Text);

 

//Сериализация логина, введенного в текстовое поле

 

 

textBoxLogin

 

 

this.m2 =

 

20

SerializeAndDeserialize.Serialize(textBoxPassword.Text);

 

//Сериализация пароля, введенного в текстовое поле

 

 

textBoxPassword

 

21

this.cm.First = this.m1; //«Упаковка» сообщения m1 с

 

логином в пакет cm

 

22

this.cm.Second = this.m2; //«Упаковка» сообщения m2 с

 

паролем в пакет cm

 

23

this.cm.NumberStatus = 1; //«Упаковка» типа запроса (1 –

 

 

запрос на авторизацию) NumberStatus в пакет cm

 

24

this.m = SerializeAndDeserialize.Serialize(this.cm);

//Сериализация пакета с дальнейшей упаковкой в объект m

25

data = this.m.Data; //Передача массива байтов Data из

объекта m в массив data

26

stream.Write(data, 0, data.Length); //Отправка массива

 

байтов data серверу

27

if (stream.CanRead) //Если поток доступен для чтения

28

{

29

int numberOfBytesRead = 0;

30

byte[] readingData = new byte[6297630];

31

do

32

{

 

numberOfBytesRead = stream.Read(readingData, 0,

33

readingData.Length); //Считываем данные, полученные от

 

сервера, в массив байтов readingData

34

}

35

while (stream.DataAvailable);

36

this.m.Data = readingData;

 

this.cm =

37

(ComplexMessage)SerializeAndDeserialize.Deserialize(m);

 

//Поэтапно десериализуем массив байтов для восстановления

 

объектов из полученного пакета

38

if (cm.NumberStatus == 2) //Если статус запроса «Успешная

 

авторизация»

39

{

40

ComplexMessage complexMessage = (ComplexMessage)

 

SerializeAndDeserialize.Deserialize(m);

41

User user1 = (User)

SerializeAndDeserialize.Deserialize(complexMessage.First);

42

Professor professor;

43

Student student = (Student)

SerializeAndDeserialize.Deserialize(complexMessage.Second);

44

if (user1.Role == "Студент")

45

{

46

user1.Student = student;

 

this.FormStudentAccount = new FormStudentAccount(this,

47

user1); //Создаем экземпляр формы личной страницы студента

 

и заполняем её содержимое

48

this.FormStudentAccount.Show();

49

this.FormStudentAccount.Text = "Профиль " +

 

user1.Student.Name;

 

28

50

this.FormStudentAccount.labelStudentName.Text = "Добро

пожаловать, " + user1.Student.Name;

51

this.FormStudentAccount.Visible = true;

52

this.Visible = false;

53

return;

54

}

55

else if (user1.Role == "Преподаватель")

56

{

57

professor = user1.Professor;

58

this.FormProfessorAccount = new FormProfessorAccount(this,

 

user1, user1.Professor);

59

this.FormProfessorAccount.Text = "Профиль " +

user1.Professor.Name;

60

this.FormProfessorAccount.labelProfessorName.Text = "Добро

пожаловать, " + user1.Professor.Name;

61

this.FormProfessorAccount.Visible = true;

62

this.Visible = false;

63

return;

64

}

65

}

66

else if (cm.NumberStatus == 3) //Если статус запроса

 

«Ошибка авторизации»

67

{

68

MessageBox.Show("Неверный логин или пароль");

69

}

70

}

71

}

 

5. Создание и форматирование DOCX файла

DocX1 - это библиотека .NET, которая позволяет разработчикам легко и интуитивно управлять файлами Microsoft Word. Библиотеку DocX можно добавить в проект при помощи установщика пакетов NuGet.

1 С другими методами библиотеки DocX можно ознакомиться на сайте https://progtask.ru/rabota-s-word-pri-pomoshi-c-sharp/

29

Рисунок 24.8

Предположим, что разрабатываемое приложения должно создавать заполненное задание на дипломный проект для согласования темы. Часть документа, которая будет генерироваться программой с использованием библиотеки DocX, представлена на рисунке 24.9.

Рисунок 24.9 – Генерируемый документ

Документ условно делится на параграфы, представляющие собой абзацы с

элементами наполнения (текстом, таблицами, ссылками, изображениями и т.д.). DocX 30