ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2019

Просмотров: 101

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

ЛАБОРАТОРНАЯ РАБОТА №2

ПРОГРАММИРОВАНИЕ СОКЕТОВ. ПРОТОКОЛ UDP


Студента ИТ 14-1 Красовского Абхая


Цель работы: изучить возможности протокола UDP для создания приложений клиент-сервер в синхронном режиме..


Ход работы:

Сервер:

#pragma comment(lib, "Ws2_32.lib") // подключение библиотеки Winsock2


#include <iostream>

#include <winsock2.h>

#define PORT 777 // порт сервера


using namespace std;


void main()

{

system("color 1A");

char buff[1024];

cout << "UDP Server\n";

// Шаг 1 - подключение библиотеки

if (WSAStartup(0x202, // номер версии библиотеки (Winsock)

(WSADATA *)&buff[0]))

cout << "WSAStartup error: " << WSAGetLastError() << endl;


// Шаг 2 - создание сокета

SOCKET my_sock;

my_sock = socket(AF_INET, // семейство используемых протоколов

SOCK_DGRAM, // тип создаваемого потока

0); // транспортный протокол(0 - значение по умолчанию, TDP для потоковых сокетов, UDP для дейтаграммных)

if (my_sock == INVALID_SOCKET)

{

cout << "Socket() error: " << WSAGetLastError() << endl;

WSACleanup();

}


// Шаг 3 - связывание сокета с локальным адресом

sockaddr_in local_addr;

local_addr.sin_family = AF_INET;

local_addr.sin_addr.s_addr = INADDR_ANY; // коснтанта(0), указывается для связки сервера с несколькими IP-адресами

local_addr.sin_port = htons(PORT);

// функция связывания сокета с локальный адресом

if (bind(my_sock, (sockaddr *)&local_addr, sizeof(local_addr)))

{

cout << "bind error: " << WSAGetLastError() << endl;

closesocket(my_sock);

WSACleanup();

}


// Шаг 4 - обработка пакетов, присланных клиентами

while (true)

{

sockaddr_in client_addr;

int client_addr_size = sizeof(client_addr);

// recvfrom - функция для считывания входящих сообщений

int bsize = recvfrom(my_sock, // сокет через который будем считывать сообщения

&buff[0], // ссылка на первый символ буфера, в который копируется сообщение

sizeof(buff) - 1, // размер буфера

0, // флаги (0 - по умолчанию)

(sockaddr *)&client_addr, // адрес, с которого будем читать сообщения

&client_addr_size); // размер сообщения, которое считываем

if (bsize == SOCKET_ERROR)

cout << "recvfrom() error: " << WSAGetLastError() << endl;

// определяем IP-адрес клиента и прочие атрибуты

HOSTENT *hst;

hst = gethostbyaddr((char *)&client_addr.sin_addr,

4, // длинна адреса в байтах

AF_INET); // тип адреса


printf("+%s [%s:%d] new DATAGRAM!\n", (hst) ? hst->h_name : "Unknown host",

inet_ntoa(client_addr.sin_addr),

/* Функция inet_ntoa() преобразует IP-адрес client_addr.sin_addr,

заданный в сетевом порядке расположения байтов,

в стандартный строчный вид, из номеров и точек..*/

ntohs(client_addr.sin_port));

/* Функция ntohs() преобразует сетевой порядок расположения

байтов положительного короткого целого netshort в узловой

порядок расположения байтов.*/


// добавление завершающего нуля

buff[bsize] = 0;

// вывод на экран

cout << "Client to Server:\n" << &buff[0] << endl;

// посылка дейтаграммы клиенту

sendto(my_sock, &buff[0], bsize, 0, // флаги (0 - по умолчанию)

(sockaddr *)&client_addr, sizeof(client_addr));

}

}


Клиент:

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


#include <iostream>

#include <string.h>

#include <winsock2.h>

#include <windows.h>


#define PORT 777

#define SERVERADDR "127.0.0.1"


using namespace std;


void freeWsaAndSocket(SOCKET socket)

{

closesocket(socket);

WSACleanup();

}


void main()

{

system("color 1A");

char buff[1024];

cout << "UDP-Client\nType quit to quit\n";


// Шаг 1 - инициализация библиотеки Winsock

if (WSAStartup(0x202, (WSADATA *)&buff[0]))

cout << "WSAStartup error: %d\n" << WSAGetLastError() << endl;


// Шаг 2 - открытие сокета

SOCKET my_sock = socket(AF_INET, SOCK_DGRAM, 0);

if (my_sock == INVALID_SOCKET)

{

cout << "socket() error: %d\n" << WSAGetLastError() << endl;

WSACleanup();

}


// Шаг 3 - обмен сообщений с сервером


HOSTENT *hst;

sockaddr_in dest_addr;

dest_addr.sin_family = AF_INET;

dest_addr.sin_port = htons(PORT);

// определение IP_адреса узла

if (inet_addr(SERVERADDR)) /* Функция inet_addr() преобразует обычный вид IP-адреса

(из номеров и точек) в двоичный код в сетевом порядке

расположения байтов. Если входящий адрес неверен, то возвращается -1. */

dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR);

else

if (hst = gethostbyname(SERVERADDR))

dest_addr.sin_addr.s_addr = ((unsigned long **)hst->h_addr_list)[0][0];

else

{

cout << "Unknown host: %d\n" << WSAGetLastError() << endl;

freeWsaAndSocket(my_sock);

}


while (true)

{

// чтение сообщения с клавиатуры

cout << "Server <= Client:";

fgets(&buff[0], sizeof(buff) - 1, stdin);

if (!strcmp(&buff[0], "quit\n")) break;


// передача сообщений на сервер

sendto(my_sock, &buff[0], strlen(&buff[0]), 0, (sockaddr *)&dest_addr, sizeof(dest_addr));


// прием сообщения с сервера

sockaddr_in server_addr;

int server_addr_size = sizeof(server_addr);

int n = recvfrom(my_sock, &buff[0], sizeof(buff) - 1, 0, (sockaddr *)&server_addr, &server_addr_size);

if (n == SOCKET_ERROR)

{

cout << "recvfrom() error: " << WSAGetLastError() << endl;

freeWsaAndSocket(my_sock);

}

buff[n] = 0;


// Вывод принятого с сервера сообщения на экран

cout << "Server to Client: " << &buff[0] << endl;

}


// Шаг последний – выход

freeWsaAndSocket(my_sock);

}


Сервер и клиент после ввода строки:

С помощью программы Wireshark отследили такую передаваемую информацию:


Смотрите также файлы