лабы / кс лаба 3
.docxМинистерство образования Республики Беларусь
Министерство образования Республики Беларусь
БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра эконмической информатики
Лабораторная работа №3
“Создание параллельного многопоточного сервера с установлением логического соединения TCP ”
Вариант 7
Выполнила: Студентка группы
972303
Рушева Маргарита
Владиславовна
Проверил: Корбит Павел
Анатольевич
Минск, 2020
Индивидуальное задание
Цель работы – изучить методы создания серверных приложений на основе установления логического соединения TCP, используя алгоритм многопоточной обработки запросов.
Задание. На сервере хранится список студентов. Каждая запись списка содержит следующую информацию о студенте:
- ФИО
- номер группы
- размер стипендии
- оценки по N предметам
Таких записей должно быть не менее пяти.
Клиент вводит с клавиатуры букву алфавита, по которой он хотел бы посмотреть информацию о студентах, и посылает ее на сервер. Назад он получает список только тех студентов, фамилии которых начинаются на эту букву.
Код программы
Сервер:
//#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <WinSock2.h>
#include <cstring>
#include <string>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable: 4996)
using namespace std;
struct students
{
string name;
int group;
double scholarship;
double marks;
};
students table[5];
DWORD WINAPI ThreadFunc(LPVOID client_socket) // функция для каждого потока
{
setlocale(LC_ALL, "RUSSIAN");
SOCKET soc = ((SOCKET*)client_socket)[0];
char str[10];
char sendstr[10];
recv(soc, str, 10, 0); // принимает строку
string users_subj = "";
int k = 0;
while (str[k] != '\0') { // переносит её в другую строку, чтобы убрать ненужные символы
users_subj.push_back(str[k]);
k++;
}
cout << users_subj;
for (int i = 0; i < 5; i++) { // цикл по всем студентам
if (table[i].name[0] == users_subj[0]) // проверяет первую букву
{
table[i].name.copy(sendstr, table[i].name.size() + 1);
sendstr[table[i].name.size()] = '\0';
send(soc, sendstr, sizeof(sendstr), 0); // посылает на сервер
}
}
send(soc, "7", sizeof("7"), 0); // посылает код, что передача закончилась
closesocket(soc);
return 0;
}
int main()
{
setlocale(LC_ALL, "RUSSIAN");
table[0].scholarship = table[1].scholarship = table[2].scholarship = table[3].scholarship
= table[4].scholarship = 70.2;
table[0].name = "SERGEEV"; table[1].name = "IGOREV"; table[2].name = "IVANOV";
table[3].name = "SVETLOV"; table[4].name = "PETROV";
table[0].group = table[2].group = table[4].group = 972304;
table[1].group = table[3].group = 972303;
for (int i = 0; i < 5; i++)
{
table[i].marks = i + 3;
cout << table[i].name << endl << "№ группы " << table[i].group << endl << "По скольким предметам стоят оценки в системе: "
<< table[i].marks << endl <<"Стипендия "<< table[i].scholarship << endl << endl;
}
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0)
return 0;
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(1280);
local_addr.sin_addr.s_addr = 0;
bind(s, (sockaddr*)&local_addr, sizeof(local_addr));
listen(s, 5);
cout << "Сервер готов к приему!" << endl << endl;
SOCKET client_socket;
sockaddr_in client_addr;
int client_addr_size = sizeof(client_addr);
while (client_socket = accept(s, (sockaddr*)&client_addr, &client_addr_size)) //принимает запрос
{
DWORD thID;
CreateThread(NULL, NULL, ThreadFunc, &client_socket, NULL, &thID); // создаёт новый поток
}
return 0;
}
Клиент:
#include <iostream>
#include <WinSock2.h>
#include "conio.h"
#include <cstring>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable: 4996)
using namespace std;
int main()
{
setlocale(LC_ALL, "RUSSIAN");
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0)
return 0;
bool flag = true;
while (flag) // бесконечный цикл для создания новых запросов
{
SOCKET s = socket(AF_INET, SOCK_STREAM, 0); // создание сокета
sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(1280);
dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(s, (sockaddr*)&dest_addr, sizeof(dest_addr)); // подключение к серверу
cout << "Введите первую букву фамилии" << endl;
char name[10];
cin >> name;
send(s, name, sizeof(name), 0); // посылает букву
char accepted_string[10];
cout << "Студенты, имя которых начинается на эту букву:" << endl;
while (true) {
recv(s, accepted_string, sizeof(accepted_string), 0); // принимает в цикле ответ сервера
if (accepted_string[0] == '7') break; // проверяет, не закончилась ли передача
cout << accepted_string << endl;
}
closesocket(s); // закрывает сокет
cout << "Хотите ли вы продолжить? (Y/N)" << endl;
while (true)
{
char sym = _getch();
if (sym == 'Y' || sym == 'y')
break;
else
if (sym == 'N' || sym == 'n')
{
flag = false; // выход из цикла
break;
}
}
}
WSACleanup();
return 0;
}