Файл: Отчет по лабораторной работе 2 дисциплины Сети эвм и телекоммуникации.docx
Добавлен: 03.05.2024
Просмотров: 13
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
МИНОБРНАУКИ РОССИИ
ВЛАДИВОСТОКСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНСТИТУТ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ
КАФЕДРА ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И СИСТЕМ
ОТЧЕТ
по лабораторной работе №2
дисциплины «Сети ЭВМ и телекоммуникации»
Студент
гр. БИС-21-02 Г.Ю. Ковригин
Преподаватель М.А. Сачко
Владивосток 2022
Задание
Цель работы.
Создать клиент/серверное сетевое приложение для обмена текстовыми сообщениями через среду передачи данных стека TCP/IP.
Для реализации приложения необходимо использовать потоковые сокеты протокола TCP.
Технические требования.
-
Перед подключением, у клиента должна быть возможность ввода адреса сервера. -
Данные передаваемые от клиента серверу могут передаватся попеременно. -
После инициализации соединения, клиенту предоставляется возможность передать сообщение серверу. -
Сервер, получив сообщение от клиента, должен предоставить возможность пользователю ответить на присланное сообщение. -
Сервер и клиент после получения сообщения должен вывести его содержимое пользователю. -
Вывод сообщения пользователю должен сопровождаться идентификатором компьютера, который его отправил (к примеру: IP-адресом, портом).
Справка.
Всю справочную информацию можно получить в ЭОС ВГУЭС по адресу электронного курса:
https://edu.vvsu.ru/course/view.php?id=27703#section-4
Выполнение работы
1. Описание программы.
Данная программа реализует функции передачи сообщений в консоли от одного компьютера другому с помощью потоковых сокетов протокола TCP. Программа состоит из двух модулей:
- серверного,
- клиентского.
Сервер принимает сообщения от клиента, а затем дает пользователю возможность ответить на сообщение клиента.
Клиент также получает сообщения от сервера и имеет возможность ответить. Обмен сообщениями продолжается пока клиент или сервер не введет команду quit.
2. Инструкция пользователя.
-
Сначала запускаем серверное приложение, при его запуске программа просит пользователя ввести номер порта, который будет использоваться этой программой, эта информация необходима для клиентской части приложения, чтобы знать на какой порт подключаться. -
После ввода номера порта, если он верный, приложение выдает сообщение о том, что ожидает подключения, далее происходит запуск клиентской части приложения. -
Переходим к запуску клиентской части приложения - программа просит ввести пользователя порт, который использует серверная часть приложения, а также, ip-адрес компьютера, на котором она находится. -
Если данные были введены корректно, произойдет подключение и пользователю будет выдана об этом информация, также от сервера придет сообщение приветствия, после чего, у пользователя будет возможность ввода сообщения для отправки на сервер.
3. Описание исходного кода программы.
Описание каждой функции будет указанно в комментариях.
DWORD WINAPI WorkToClient(LPVOID client_socket)
{
const int sizeBuff = 1024; // размер буфера обмена сообщений
SOCKET my_sock; // создаем новый сокет
my_sock=((SOCKET *) client_socket)[0]; // заполняем данными клиента
char buff[sizeBuff]; // создаем буфер для обмена сообщениями
#define sHELLO "Hello\n" // макрос приветствия
// отправляем клиенту приветствие
send(my_sock,sHELLO,sizeof(sHELLO),0);
// цикл эхо-сервера: прием строки от клиента и
// возвращение ее клиенту
int nsize;
while( (nsize=recv(my_sock,buff,sizeof(buff)-1,0))!=SOCKET_ERROR )
{
// ставим завршающий ноль в конце строки
buff[nsize]='\0';
// выводим на экран
printf("New message of client: %s\n",buff);
// читаем пользовательский ввод с клавиатуры
cout <<"Response: ";
cin.getline(buff,sizeBuff);
// проверка на "quit"
if (!strcmp(buff,"quit"))
{
// Корректный выход
printf("Exit...");
closesocket(my_sock);
WSACleanup();
return 0;
}
// отвечаем клиенту
send(my_sock,buff,sizeBuff,0);
}
printf("Recv error %d\n",WSAGetLastError());
closesocket(my_sock); //закрываем сокет
WSACleanup(); //прекращаем использование библеотки Winsock 2
return -1;
}
Выше был описан код серверной части программы, ниже будет представлена клиентская часть работает полностью аналогичным образом, разница лишь в том, что в клиенте передается/принимается дескриптор сокета сервера.
using namespace std;
const int sizeBuff = 1024;
int main()
{
int PORT;
char SERVERADDR[9];
printf("Input port server: ");
cin >>PORT;
cin.get();
printf("Input ip address: ");
scanf("%s",&SERVERADDR);
cin.get();
char buff[sizeBuff];
// Шаг 1 - инициализация библиотеки Winsock
if (WSAStartup(0x202,(WSADATA *)&buff[0]))
{
printf("WSAStart error %d\n",WSAGetLastError());
return -1;
}
// Шаг 2 - создание сокета
SOCKET my_sock;
my_sock=socket(AF_INET,SOCK_STREAM,0);
if (my_sock < 0)
{
printf("Socket() error %d\n",WSAGetLastError());
return -1;
}
// Шаг 3 - установка соединения
// заполнение структуры sockaddr_in
// указание адреса и порта сервера
sockaddr_in dest_addr;
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(PORT);
HOSTENT *hst;
// преобразование IP адреса из символьного в
// сетевой формат
if (inet_addr(SERVERADDR)!=INADDR_NONE)
dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
else
{
printf("Invalid address %s\n",SERVERADDR);
closesocket(my_sock);
WSACleanup();
return -1;
}
// адрес сервера получен – пытаемся установить
// соединение
if (connect(my_sock,(sockaddr *)&dest_addr,sizeof(dest_addr)))
{
printf("Connect error %d\n",WSAGetLastError());
return -1;
}
printf("Connect to %s succes\n\
Type quit for quit\n\n",SERVERADDR);
// Шаг 4 - чтение и передача сообщений
int nsize;
char buffMessage[sizeBuff];
while((nsize=recv(my_sock,buffMessage,sizeof(buffMessage)-1,0))!=SOCKET_ERROR)
{
// ставим завршающий ноль в конце строки
buffMessage[nsize]='\0';
// выводим на экран
printf("New message of server: %s\n",buffMessage);
// читаем пользовательский ввод с клавиатуры
printf("Response: ");
cin.getline(buffMessage,sizeBuff);
// проверка на "quit"
if (!strcmp(buffMessage,"quit"))
{
// Корректный выход
printf("Exit...");
closesocket(my_sock);
WSACleanup();
system("pause");
return 0;
}
// передаем строку клиента серверу
send(my_sock,buffMessage,sizeBuff,0);
}
printf("Recv error %d\n",WSAGetLastError());
closesocket(my_sock);
WSACleanup();
system("pause");
return -1;
}