Создание последовательного сервера с установлением логического соединения (TCP/IP)

Подробнее

Размер

231.20K

Добавлен

20.11.2020

Скачиваний

50

Добавил

Моника
Клиент посылает два числа серверу и одну из математических операций: *, /, +, -, -сервер соответственно умножает, делит, складывает либо вычитает эти два числа и посылает ответ назад клиенту.
Текстовая версия:

Министерство образования Республики Беларусь

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ

Кафедра экономической информатики

Лабораторная работа №1

Создание последовательного сервера с установлением логического соединения (TCP/IP)

Проверил: Выполнил:

Корбит Павел Студент группы

Анатольевич 972301

Хвесько Моника

Александровна

Минск, 2020

Задание

Клиент посылает два числа серверу и одну из математических операций: *, /, +, -, -сервер соответственно умножает, делит, складывает либо вычитает эти два числа и посылает ответ назад клиенту.

Код программы

Серверная часть

#include<iostream>

#pragma comment(lib, "ws2_32.lib")

#include<winsock2.h>//библиотека,позволяющая реализовывать интерфейс winsock

#pragma warning(disable:4996)

using namespace std;

int main(int argc, char* argv[]) {

//функции загрузки библиотеки

WSAData wsaData;

WORD DLLVersion = MAKEWORD(2, 1);

//проверка загрузки библиотеки

//параметр функции WSAStartup() – это значение типа word, которое определяет

//максимальный номер версии WinSock, доступный приложению. Второй параметр – структура

//wsaData – содержит номер версии, которая должна использоваться

if (WSAStartup(DLLVersion, &wsaData) != 0) {

cout << "Error" << endl;

exit(1);

}

//заполнить инфу об адресе сокета

SOCKADDR_IN addr;//структура для хранения адреса

int sizeofaddr = sizeof(addr);

addr.sin_addr.s_addr = inet_addr("127.0.0.1");//хранение IP адреса

addr.sin_port = htons(1111);//выбор порта

addr.sin_family = AF_INET;//семейство интернет-протоколов

// Поле sin_family всегда имеет значение AF_INET.

//создание сокета sListen и присвоение ему результата функции

//socket(int domain, int type, int protocol)

SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);

//привязка адреса сокету

// bind(int fd, struct sockaddr *local_addr, socklen_t addr_length)

bind(sListen, (SOCKADDR*)&addr, sizeof(addr));

//прослушивание порта

//SOMAXCONN-макс значение запросов для обработки

listen(sListen, SOMAXCONN);

//новый сокет для соединения с клиентом

SOCKET newConnection;

newConnection = accept(sListen, (SOCKADDR*)&addr, &sizeofaddr);

//после соединения ссылка newConnection будет содержать сведения об IP адресе клиента,

//который произвел подключение

//accept() возвращает указатель на новый сокет для общения с клиентов, если 0, то подключение не удалось

if (newConnection == 0) {

cout << "Error #2"<<endl;

}

else {

cout << "Client connected" << endl;

}

//индивидуальное задание

char message[256] = "Enter two numers >> ";

send(newConnection, message, sizeof(message), NULL);

char num1[256], num2[256];

recv(newConnection, num1, sizeof(num1), 0);

recv(newConnection, num2, sizeof(num2), 0);

cout << "Two numbers received: " << num1 << ", " << num2 << endl;

//преобразованиие строки в int

int a = atoi(num1);

int b = atoi(num2);

char message1[256] = "Enter operator ""*"",""/"",""+"",""-"" >> ";

send(newConnection, message1, sizeof(message), NULL);

char calcul;

recv(newConnection, &calcul, sizeof(calcul), 0);

cout << "Operator received: " << calcul <<"("<<int(calcul)<<")"<< endl;

double result=0;

switch (int(calcul)) {

case 42:result = a * b; break;

case 47:result = a / b; break;

case 43:result = a + b; break;

case 45:result = a - b; break;

}

cout << a <<" "<< calcul <<" "<< b << " = " << result;

char message3[256];

itoa(result,message3,10);

send(newConnection, message3, sizeof(message3), 0);

closesocket(newConnection);

WSACleanup();

return 0;

}

Клиентская часть

#include<iostream>

#pragma comment(lib, "ws2_32.lib")

#include<winsock2.h>

#include<conio.h>

#pragma warning(disable:4996)

using namespace std;

int main(int argc, char* argv[]) {

//функции загрузки библиотеки

WSAData wsaData;

WORD DLLVersion = MAKEWORD(2, 1);

//проверка загрузки библиотеки

if (WSAStartup(DLLVersion, &wsaData) != 0) {

cout << "Error" << endl;

exit(1);

}

//заполнить инфу об адресе сокета

SOCKADDR_IN addr;//структура для хранения адреса

int sizeofaddr = sizeof(addr);

addr.sin_addr.s_addr = inet_addr("127.0.0.1");//хранение IP адреса

addr.sin_port = htons(1111);//выбор порта

addr.sin_family = AF_INET;//семейство интернет-протоколов

//создание нового сокета для соединения с сервером

SOCKET Connection = socket(AF_INET, SOCK_STREAM , NULL);

//присоединение к серверу и проверка

if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) {

cout << "Error! Failed connect to server" << endl;

return 1;

}

cout << "Connected!" << endl;

//индивидуальное задание

//создаем массив char для принятия сообщения Server

char message[256];

recv(Connection, message, sizeof(message), NULL);

cout << message;

int number;

char numberChar[256];

for (int i = 0; i < 2; i++) {

cin >> number;

_itoa(number, numberChar, 10);//преобразование int в строку

send(Connection, numberChar, sizeof(numberChar), 0);

}

char message1[256];

recv(Connection, message1, sizeof(message), NULL);

cout << message1;

char calcul;

cin >> calcul;

send(Connection, &calcul, sizeof(calcul), 0);

char message3[256];

recv(Connection, message3, sizeof(message), 0);

cout << "Result = " << message3;

closesocket(Connection);

WSACleanup();

return 0;

}

Результат работы программы

Основная информация изученная в ходе работы над лабораторной работой

Протокол – набор правил и действий (очерёдности действий), позволяю- щий осуществлять соединение и обмен данными между двумя и более вклю- чёнными в сеть устройствами.

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

Transmission Control Protocol/Интернет Protocol (TCP/IP) – это промыш- ленный стандарт стека протоколов, разработанный для глобальных сетей.

Лидирующая роль стека TCP/IP объясняется следующими его свойствами:

Единицей данных протокола TCP является сегмент. Информация, посту- пающая к протоколу TCP в рамках логического соединения от протоколов бо- лее высокого уровня, рассматривается протоколом TCP как неструктурирован- ный поток байтов. Поступающие данные буферизуются средствами TCP. Для передачи на сетевой уровень из буфера «вырезается» некоторая непрерывная часть данных, называемая сегментом.

Не все сегменты, посланные через соединение, будут одного и того же размера, однако оба участника соединения должны договориться о максималь- ном размере сегмента, который они будут использовать. Этот размер выбирается таким образом, чтобы при упаковке сегмента в IP-пакет он помещался туда целиком, то есть максимальный размер сегмента не должен превосходить максимального размера поля данных IP-пакета. В противном случае пришлось бы выполнять фрагментацию, то есть делить сегмент на несколько частей, для того чтобы он вместился в IP-пакет.

Соединение в протоколе TCP идентифицируется парой полных адресов обоих взаимодействующих процессов (оконечных точек). Адрес каждой из оконечных точек включает IP-адрес (номер сети и номер компьютера) и номер порта. Одна оконечная точка может участвовать в нескольких соединениях.

Установление соединения выполняется в следующей последовательности:

Алгоритм работы последовательного сервера с установлением логического соединения:

1. Создать сокет и установить связь с локальным адресом.

2. Перевести сокет в пассивный режим, подготавливая его для использования сервером.

3. Принять из сокета следующий запрос на установление соединения и получить новый сокет для соединения.

4. Считывать в цикле запросы от клиента, формировать ответы и отправлять клиенту.

5. После завершения обмена данными с конкретным клиентом закрыть соединение и возвратиться к этапу 3 для приема нового запроса на установление соединения.