Создание последовательного сервера с установлением логического соединения (TCP/IP)
Предмет
Тип работы
Факультет
Преподаватель
Министерство образования Республики Беларусь
БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра экономической информатики
Лабораторная работа №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 для приема нового запроса на установление соединения.