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

Лабораторные работы / Методические указания к ЛР по ОАИП (09.02.07)

.pdf
Скачиваний:
60
Добавлен:
08.05.2022
Размер:
3.68 Mб
Скачать

 

19

while (true)

 

 

20

{

 

 

21

if (Stream.CanRead)

CanRead возвращает значение true, если поток

 

поддерживает чтение

 

 

 

 

22

{

 

 

23

byte[] myReadBuffer = new byte[6297630];

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

 

принимаемых от клиента

 

 

 

 

24

do

 

 

25

{

 

 

26

Stream.Read(myReadBuffer, 0, myReadBuffer.Length);

Запись данных, считанных с потока Stream, в

 

массив байтов myReadBuffer

 

 

 

 

27

}

 

 

28

while (Stream.DataAvailable);

Пока данные есть в потоке Stream

 

29

Student student;

 

 

30

Professor professor;

 

 

31

User user;

 

 

32

MyLib.ComplexMessage complexMessage = new

 

 

ComplexMessage();

 

 

33

MyLib.Message message = new MyLib.Message();

 

 

34

message.Data = myReadBuffer;

Запись принятого пакета данных с клиента в

 

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

 

 

 

 

35

complexMessage = (ComplexMessage)

Десериализация полученного пакета message в

 

SerializeAndDeserialize.Deserialize(message);

объект complexMessage

 

 

 

 

 

36

if (complexMessage.NumberStatus == 0)

Если NumberStatus, сообщающий о типе

 

запроса, равен 0

 

 

 

 

37

{

…то выполняется запрос на добавление нового

 

пользователя в базу данных

 

 

 

261

 

38

try

 

 

39

{

 

 

 

student = (Student)SerializeAndDeserialize.

Десериализуется свойство First сложного

 

40

пакета complexMessage и результат

 

Deserialize(complexMessage.First);

 

 

 

записывается в переменную student

 

41

}

 

 

42

catch

 

 

43

{

 

 

 

 

Если в строке 40 произойдет ошибка при

 

44

student = null;

преобразовании типов, то переменной student

 

 

 

присвоится нулевой объект null

 

45

}

 

 

46

try

 

 

47

{

 

 

 

professor = (Professor)SerializeAndDeserialize.

Десериализуется свойство First сложного

 

48

пакета complexMessage и результат

 

Deserialize(complexMessage.First);

 

 

 

записывается в переменную professor

 

49

}

 

 

50

catch

 

 

51

{

 

 

 

 

Если в строке 48 произойдет ошибка при

 

52

professor = null;

преобразовании типов, то переменной student

 

 

 

присвоится нулевой объект null

 

53

}

 

 

 

user = (User)SerializeAndDeserialize.

Десериализуется свойство Second сложного

 

54

пакета complexMessage и результат

 

Deserialize(complexMessage.Second);

 

 

 

записывается в переменную user

262

 

55

using (EntityModelContainer db = new

Создается экземпляр контекста данных для

 

 

EntityModelContainer())

взаимодействия с базой данных

 

 

56

{

 

 

 

 

 

Обращение к коллекции UserSet для добавления

 

 

57

db.UserSet.Add(user);

нового объекта user в таблицу UserSet базы

 

 

 

 

данных

 

 

58

db.SaveChanges();

Сохранение изменений, применяемых к базе

 

 

данных

 

 

 

 

 

 

59

}

 

 

 

60

}

 

 

 

 

 

 

 

 

61

else if (complexMessage.NumberStatus == 1)

Если NumberStatus, сообщающий о типе

 

 

запроса, равен 1

 

 

 

 

 

 

62

{

…то выполняется запрос на авторизацию

 

 

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

 

 

 

 

 

 

63

using (EntityModelContainer db = new

Создается экземпляр контекста данных для

 

 

 

EntityModelContainer())

взаимодействия с базой данных

 

 

64

{

 

 

 

65

byte[] responseData;

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

 

 

формируемого сервером на запрос клиента

 

 

 

 

 

 

66

for (int i = 0; i < db.UserSet.ToList().Count;

Циклический перебор всех пользователей из

 

 

i++)

таблицы UserSet

 

 

67

{

 

 

 

 

if (db.UserSet.ToList()[i].Login ==

Условие проверки соответствия логина и пароля

 

 

 

Convert.ToString(SerializeAndDeserialize.

 

 

 

i-го пользователя из коллекции –UserSet логину

 

 

68

Deserialize(complexMessage.First)) &&

 

 

и паролю, полученными в результате запроса от

 

 

 

db.UserSet.ToList()[i].Password ==

 

 

 

клиента

 

 

 

Convert.ToString(SerializeAndDeserialize.

 

 

 

 

 

263

 

 

Deserialize(complexMessage.Second)))

 

 

69

{

 

 

 

 

Создаем объект user1 и копируем в него i-й

 

70

User user1 = db.UserSet.ToList()[i];

элемент коллекции UserSet, для которого

 

 

 

выполнилось условие в строке 68

 

 

 

Создаем объект user2, вызываем для него

 

 

 

конструктор по умолчанию и инициализируем

 

71

User user2 = new User() { Login = user1.Login,

его свойства, скопировав значения свойств

 

 

Password = user1.Password, Role = user1.Role };

объекта user1. Данное действие необходимо для

 

 

 

дальнейшей корректной десериализации объекта

 

 

 

класса User со стороны клиента.

 

72

m1 = SerializeAndDeserialize.Serialize(user2);

Сохранение в переменную m1 сериализованного

 

значения объекта user2

 

 

 

 

73

if (db.UserSet.ToList()[i].Role == "Студент")

Если роль пользователя – студент

 

74

{

 

 

 

 

Создаем объект student1 и копируем в него

 

75

Student student1 = db.UserSet.ToList()[i].Student;

значение свойства Student i-го элемента

 

коллекции UserSet, для которого выполнилось

 

 

 

 

 

 

условие в строке 73

 

 

 

Создаем объект student2, вызываем для него

 

 

Student student2 = new Student() { Name =

конструктор по умолчанию и инициализируем

 

76

student1.Name, NumberGroup = student1.NumberGroup,

его свойства, скопировав значения свойств

 

 

PersonalData = student1.PersonalData, Photo =

объекта student1. Данное действие необходимо

 

 

student1.Photo, Specialty = student1.Specialty };

для дальнейшей корректной десериализации

 

 

 

объекта класса Student со стороны клиента.

 

77

m2 = SerializeAndDeserialize.Serialize(student2);

Сохранение в переменную m2 сериализованного

 

значения объекта student2

 

 

 

264

 

78

}

 

 

79

else if (db.UserSet.ToList()[i].Role ==

Если роль пользователя – преподаватель

 

"Преподаватель")

 

 

80

{

 

 

81

Professor professor1 =

 

 

db.UserSet.ToList()[i].Professor;

Повторяем действия, аналогичные строкам 75-77,

 

82

Professor professor2 = professor1;

 

но только для объектов класса Professor

 

83

m2 =

 

 

 

 

SerializeAndDeserialize.Serialize(professor1);

 

 

84

}

 

 

85

cm.First = m1;

Свойству First объекта cm присваиваем m1

 

86

cm.Second = m2;

Свойству Second объекта cm присваиваем m2

 

 

 

Свойству NumberStatus объекта cm

 

87

cm.NumberStatus = 2;

присваиваем значение 2 (статус успешной

 

 

 

авторизации)

 

88

m = SerializeAndDeserialize.Serialize(cm);

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

 

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

 

 

 

 

89

responseData = m.Data;

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

 

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

 

 

 

 

90

Stream.Write(responseData, 0,

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

 

 

responseData.Length);

клиенту

 

91

goto label;

Прыжок к label (строка 98)

 

92

}

 

 

93

}

 

 

 

 

 

 

 

 

Свойству NumberStatus объекта cm

 

94

cm.NumberStatus = 3;

присваиваем значение 3 (статус неудачной

 

 

 

авторизации)

265

 

 

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

}}}}}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Листинг 15.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

 

266

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

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

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

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

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

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

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

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

267

 

 

 

Листинг 15.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

{

 

 

 

 

 

 

 

268

 

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

{

 

 

 

 

if (comboBoxRole.SelectedItem.ToString()

 

 

 

28

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

 

 

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

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

 

29{

Student student = new Student() { Name =

textBoxFIO.Text, NumberGroup =

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

30 int.Parse(textBoxNumGroup.Text),

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

PersonalData =

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

richTextBoxPersonalData.Text, Photo =

 

269

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

User user = new User() { Student = student, Login = textBoxLogin.Text,

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

this.InitComponentMessage(student, user,

320);

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 =

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

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

39}

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

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

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

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

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

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

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

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

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

270

Соседние файлы в папке Лабораторные работы