Flatik.ru

Перейти на главную страницу

Поиск по ключевым словам:

страница 1

Лабораторная работа 4

Теория

Сокеты


Платформа Windows предоставляет программисту еще один механизм взаимодействия процессов – сокеты, которые позволяют образовать дуплексный канал как между процессами как в пределах одной машины, так и между процессами по сети.

Для использования функций WinSock в программе на языке C необходимо включить заголовочный файл winsock2.h:

#include

и указать в свойствах сборки (линковки) программы библиотеку ws2_32.lib (Project >Properties >Configuration Properties >Linker >Input: Additional Dependencies).


До начала использования функций WinSock необходимо выполнить инициализацию WinSock с помощью функции WSAStartup:
WSADATA WSAData; // После инициализации содерж инф. о WinSock

if (WSAStartup (MAKEWORD(2,1), &WSAData;) != 0)

{

printf ("WSAStartup faild. Error: %d", WSAGetLastError ());



return FALSE;

}
На следующем рисунке изображена последовательность вызовов при реализации клиента и сервера:





Реализация сервера:


  1. Сервер создает сокет с помощью функции socket:

int WinSocket;

if ((WinSocket = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)

{

printf ("Allocating socket failed. Error: %d", WSAGetLastError ());



return -1;

}

Константа AF_INET указывает, что мы используем сокеты на основе протокола TCP/IP c адресами формата протокола IP 4-ой версии (т.е. привычный нам IP-адрес формата xxx.xxx.xxx.xxx). Константа SOCK_STREAM указывает, что мы используем протокол надежной доставки TCP.



  1. Указывает адрес и порт, на котором сервер будет ожидать входящие соединения с помощью функции bind:

#define PORTNUM 1024


SOCKADDR_IN local_sin;

// Укажем параметры локальной части сокета

local_sin.sin_family = AF_INET;

local_sin.sin_port = htons (PORTNUM); // порт на котором мы ожидаем соединения

local_sin.sin_addr.s_addr = htonl (INADDR_ANY); // привязка к адресам на всех интерфейсах
if (bind (WinSocket, (struct sockaddr *) &local;_sin, sizeof (local_sin)) == SOCKET_ERROR)

{

printf ("Binding socket failed. Error: %d", WSAGetLastError ());



closesocket (WinSocket);

return FALSE;

}

Структура SOCKADDR_IN служит для указания адресной информации сокета. В качестве адреса привязки локальной части мы выбрали все адреса, которые присвоены сетевым интерфейсам компьютера. Если мы хотим привязать к конкретному адреса, например к адресу обратной петли – 127.0.0.1, то нам необходимо использовать функцию inet_addr:



local_sin.sin_addr.s_addr = inet_addr("127.0.0.1");



  1. Открывает сокет на прослушивание запросов от клиента с помощью функции listen:

// одновременно будет принят только 1 запрос

#define MAX_PENDING_CONNECTS 1

if (listen (WinSocket, MAX_PENDING_CONNECTS) == SOCKET_ERROR)

{

printf ("Listening to the client failed. Error: %d", WSAGetLastError ());



closesocket (WinSocket);

return FALSE;

}



  1. Ожидает входящего соединения от клиента с помощью функции accept:

printf("Waiting connect from client.\n");


int ClientSock; // Сокет, который будет связан с клиентом

accept_sin_len = sizeof (accept_sin);

// Ждем входящего соединения от клиента

ClientSock = accept (WinSocket, (struct sockaddr *) &accept;_sin, (int *) &accept;_sin_len);


if (ClientSock == INVALID_SOCKET)

{

printf ("Accepting connection with client failed. Error: %d", WSAGetLastError ());



return FALSE;

}

Функция accept ждет входящего соединения от клиента, и, после удачного подключения, создает еще один сокет (возвращается в качестве результата выполнения функции), который связан исключительно с клиентом, для которого было установлено соединение. Полученный сокет можно передать отдельному потоку для выполнения операций ввода/вывода с клиентом, а основной поток может еще раз вызвать функцию accept, которая ожидает соединения от клиента.




  1. Для приема данных по сокету можно использовать функцию recv:

int recv(SOCKET s, char* buf, int len, int flags);

Параметры:

s

Сокет

buf

Указатель на буфер, в который будут помещены данные

len

Размер буфера в байтах

flags

Флаги, в нашем случае укажем 0

результат функции

  • Больше нуля – успешное выполнение, значение равно количеству прочитанных байт;

  • 0 – сокет был закрыт

  • SOCKET_ERROR - произошла ошибка, код ошибки можно получить через WSAGetLastError.

В случае, если на данный момент нету доступных данных для чтения из сокета, функция recv не возвращает управления, пока не будет доступен и прочитан хотя бы один байт. Следует знать (!!!!), что функция recv может поместить в буфер меньшее число байт, чем указано в параметре len, это может быть обусловлено тем, что на данный момент нет данных в объеме, указанном в параметре len, либо могут существовать иные причины. Поэтому если мы намереваемся прочитать некоторое фиксированное число байт из сокета, мы должны проверять результат функции recv и повторить запрос на чтение, чтобы дочитать остаток данных, если число прочитанных байт оказалось меньше ожидаемого нами.



  1. Для отправки данных по сокеты можно использовать функцию send:

int send(SOCKET s, const char* buf, int len, int flags);

Параметры:

s

Сокет

buf

Указатель на буфер, данные из которого будут переданы в сокет

len

Размер данных для передачи по сокту

flags

Флаги, в нашем случае укажем 0

результат функции

  • Больше нуля – успешное выполнение, значение равно количеству посланных байт;

  • SOCKET_ERROR - произошла ошибка, код ошибки можно получить через WSAGetLastError.


Следует знать (!!!!), что функция send может передать меньшее число байт, чем указано в параметре len. Поэтому если мы намереваемся передать некоторое фиксированное число байт по сокету, мы должны проверять результат функции send и повторить запрос на передачу остатка данных, если число переданных байт оказалось меньше ожидаемого нами.



  1. По завершению сеанса связи с клиентом или для закрытия основного сокета, на котором ожидается соединение, необходимо закрыть сокет с помощью функции closesocket:

closesocket (WinSocket);


или
closesocket (ClientSocket);

Реализация клиента


  1. Клиент, так же как и сервер, открывает потоковый сокет TCP.

  2. Подключается к серверу с помощью функции connect:

struct SOCKADDR_IN remote_sin;


remote_sin.sin_family = AF_INET;

remote _sin.sin_port = htons(PORTNUM);


// Нам необходимо указать адрес сервера. Это можно сделать двумя способами:

// 1) если известен только IP адрес сервера

remote_sin.sin_addr.s_addr = inet_addr("127.0.0.1");
// ИЛИ !
// 2) если известно имя cервера, например "localhost", или IP в виде строки "127.0.0.1"

//******* begin 2 ********

char name[] = "east-7.vvsu.ru"; // = "212.16.195.174"

struct hostent *he;

he = gethostbyname(name);

if (he == NULL)

{

printf ("Unable to get the hostname. Error: %d\n", WSAGetLastError());



return FALSE;

}

remote_sin.sin_addr.S_un.S_addr = *((long *)(he->h_addr));



// ******** end 2 ************************************
if (connect (ServerSock, (PSOCKADDR) &remote;_sin, sizeof (remote _sin)) == SOCKET_ERROR)

{

printf ("Connecting to the server failed. Error: %d", WSAGetLastError ());



closesocket (ServerSock);

return FALSE;

}



  1. Производит обмен данными с помощью функций recv и send.

  2. По завершении сеанса связи закрывает сокет с помощью функции closesocket.


Задания для самостоятельной работы

Требования


Необходимо создать клиент-серверное приложение, где клиентское приложение выполняет интерактивное взаимодействие с пользователем: ввод данных с клавиатуры и вывод результатов на экран. А серверное приложение получает от клиента набор данных для обработки и посылает результат обратно клиенту.

Передача данных между клиентом и сервером должна осуществляться с использованием сокетов TCP/IP. Для каждого подключения клиента сервер должен создавать отдельный поток, в котором будет выполняться обработка запроса пользователя. Из этого требования следует, что сервер должен корректно работать с несколькими подключенными клиентами. Логика чтения/записи данных из сокета должна корректно обрабатывать неполное чтение/запись из сокета (т.е. число прочитанных/записанных байт может отличаться от значения, указанного в параметре len), так же нужно корректно обрабатывать нулевой результат функции recv.

Данные, передаваемые через сокет, должны быть размещены в буфере приема/отправки в формате, оптимальном для обработки процессором, т.е. если в задании речь идет об обработке:


  • целых чисел - тип данных должен быть целочисленных (int или long)

  • вещественных чисел - тип данных float или double

  • строковые значения – тип ASCIIZ-строка (т.е. массив char завершающийся нулем), либо массив char, предваренный счетчиком байт в строке (как это сделано в Паскале).

Все входные значения для программы должны задаваться интерактивно (а не статически указанные значения в исходных кодах программы). Допустима/желательна реализация пользовательского интерфейса средствами консольного ввода-вывода. В случае если введенные данные являются недопустимыми, об этом необходимо информировать пользователя (разумеется, проверка на правильность данных должна выполняться в серверном приложении). После отображения результатов, пользователю необходимо дать возможность выхода из программы или переход к повторному вводу данных. Если пользователь выбирает выход из клиентского приложения, пользователю должна быть предоставлена возможность остановки сервера.
Вариант 1

Калькулятор, работающий с комплексными числами с плавающей точкой, и реализующий следующие операции: сложение, умножение, деление и вычитание. Реализовать обработку ошибок: деление на ноль.


Вариант 2

Виртуальная гадалка: в ответ на запрос пользователя должна возвращаться фраза с "предсказанием". Ограничиться набором 10-20 фраз. Реализовать обработку ошибок: ошибка должна возникать случайным образом и означает, что гадалка не знает ответ.


Вариант 3

На вход подается массив чисел, программа случайным образом перемешивает числа и выводит результат на экран. Реализовать обработку ошибок: отрицательное число элементов.


Вариант 4

Англо-русский словарь: передается слово на английском языке – возвращается его перевод. Ограничиться набором из 10 – 20 слов. Реализовать обработку ошибок: отсутствие слова в словаре.


Вариант 5

Определение високосного года: на входе подается год, на выходе булево значение результата. Реализовать обработку ошибок: неверное значение года (напр., отрицательный год)


Вариант 6

Генератор последовательности случайных чисел: на входе подается максимальное значение случайного числа и число элементов – на выходе массив полученных чисел. Реализовать обработку ошибок: отрицательное число элементов.


Вариант 7

см. вариант 22.


Вариант 8

Программа преобразования входной строки в кодировку BASE64 и обратно. Полная спецификация BASE64 содержится в RFC 1421 и RFC 2045.

Для того, чтобы преобразовать данные в BASE64 , первый байт помещается в самые старшие восемь бит 24-битного буфера, следующие в средние восемь и третий в младшие значащие восемь бит. Если кодируется менее чем три байта, то соответствующие биты буфера устанавливаются в ноль. Далее каждые шесть бит буфера, начиная с самых старших, используются как индексы строки «ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/» и её символы, на которые указывают индексы, помещаются в выходную строку. Если кодируются только один или два байта, используются только первые два или три символа строки и выходная строка дополняется двумя или одним символами «=». Это предотвращает добавление дополнительных битов к восстановленным данным. Процесс повторяется над оставшимися входными данными.
Вариант 9

Операции со множествами целых чисел: объединение, пересечение, разность.


Вариант 10

Умножение матриц: на входе массивы произвольных размерностей (k,m) и (i,j). Реализовать обработку ошибок: невозможность перемножения матриц вследствие несовпадения размерностей.


Вариант 11

Замена вхождения одной последовательности в строке символов на другую последовательность символов. Реализовать обработку ошибок: искомый шаблон не найден.


Вариант 12

Поиск числа в целочисленном массиве. Реализовать обработку ошибок: искомое число не найдено.


Вариант 13

Замена порядка символов во входной строке на обратный.


Вариант 14

Генерация последовательности Фибоначчи: на входе начальные параметры последовательности F0 и F1 и длина ряда. Формула ряда следующая: Fn = Fn-1 + Fn-2


Вариант 15

Решение линейного уравнения вида y = a*x + b. Входные параметры: a и b и у. На выходе найденное значение x. Реализовать обработку ошибок: значение параметра a = 0.


Вариант 16

Игра "Угадай число": программа «загадывает» число, пользователь пытается угадать это число, программа сообщает, что либо число угадано, либо больше или меньше загаданное число относительно числа, указанного пользователем. Если пользователь заново начинает игру, то программа загадывает новое число.


Вариант 17

Генерации монотонной последовательности простых чисел, начиная с 1. Программе указывается число чисел в последовательности. Реализовать обработку ошибок: отрицательное число элементов.


Вариант 18

Нахождение корней квадратного уравнения a*x2 + b*x + c = 0. Реализовать обработку ошибок: отсутствие решения в действительных числах.


Вариант 19

Генерации геометрической прогрессии: на входе начальный член b0 и число q (знаменатель геометрической прогрессии) и число генерируемых членов. Проверка на ошибки: начальный член должен быть отличен от нуля.


Вариант 20

Интерфейс хеш-функции (или, иначе говоря, цифровой подписи):



  • получение хеш-значения для входной строки

  • проверка соответствия входной строки указанному хеш-значению

Указание: для простоты реализации рекомендуется выбрать в качестве хеш-значения беззнаковое длинное целое (т.е. unsigned long int).


Вариант 21

Решение системы линейных уравнений вида:

a11x1 + a12x2 = b1

a21x1 + a22x2 = b2

На вход подается матрица A с коэффициентами aij и вектор B с коэффициентами bi; на выходе – вектор Х, содержащий найденные значения xi. Реализовать проверку на ошибки: отсутствие решения.
Вариант 22

Векторная арифметика: сложение, вычитание, скалярное произведение векторов. Реализовать проверку на ошибки: несовпадение размерностей операндов.


Вариант 23

Получение производной многочлена следующего вида


a0 + a1x + a2x2 + … + anxn . На вход подается массив коэффициентов ai, на выходе bi – коэффициенты результирующего полинома.
Вариант 24

Подсчета частоты встречаемости символов в текстовой строке: на вход подается текстовая строка (ASCII-8, т.е. 8-битные строки), на выходе массив частот.


Вариант 25

Разбор текстовой строки, содержащей дату и время. Входная строка может иметь следующие форматы:



  • "год-месяц-день часы:минуты:секунды"

  • "часы:минуты:секунды год-месяц-день"

  • "год/месяц/день часы:минуты:секунды"

  • "часы:минуты:секунды год/месяц/день"

На выходе шесть чисел, которые соответствуют году, месяцу, дню, и т.д. Реализовать проверку на ошибки: неверный формат входной строки, неверное значение года (отрицательное), месяца (вне диапазона 1..12), и т.д.
Вариант 26

Проверка принадлежности точки вещественной плоскости с координатами (X1, Y1) к окружности, заданной координатами центра (X2, Y2) и радиусом R. Реализовать проверку на ошибки: отрицательный радиус.


Вариант 27

Для каждого целого положительного числа N существует его представление в виде произведения k взаимно простых сомножителей pi с показателем степени ni ≥ 1:



Такое представление единственно, с точностью до порядка следования сомножителей. Если, например, положить pi > pj, для i > j, тогда такое разложение становится полностью определенным единственным образом.

Таким образом, необходимо реализовать программу разложения числа на простые множители. На вход подается число N, на выходе – разложение числа на сомножители согласно приведенной выше формуле.

Реализовать проверку на ошибки: N – отрицательное или нулевое число.


Вариант 28

Построение гистограммы. На вход подается массив целых чисел, начало отсчета интервалов и размер интервала. Программа считает число попавших чисел в каждый из интервалов и выводит на экран эти значения. Реализовать проверку на ошибки: отрицательное число элементов, отрицательный или нулевой размер интервала.


Вариант 29

Реализовать программу генерации последовательность чисел на основании следующего алгоритма. Имеется некоторое число K (т.н. модуль) и некоторое начальное значение отличное от нуля. Тогда, где mod – остаток от деления. Для некоторого значения i полученное значение будет совпадать с начальным значением, т.е. – это служит признаком конца алгоритма. Таким образом, на вход подаются входные параметры K и . На выходе – массив, содержащий полученную последовательность. Реализовать проверку на ошибки: модуль меньше 2, начальное значение меньше 1.


Вариант 30

Реализовать программу, которая получает массив целых чисел. В этой последовательности необходимо найти простые числа. Найденные простые числа необходимо вывести на экран.

Лабораторная работа 4 Теория Сокеты

Платформа Windows предоставляет программисту еще один механизм взаимодействия процессов – сокеты, которые позволяют образовать дуплексный канал как между процессами как в пределах

122.62kb.

10 10 2014
1 стр.


Лабораторная работа №1 Работа в Oracle Database Express Edition 1 Лабораторная работа №6

Лабораторная работа Выполнение расчетов с использованием программирования в среде Visual Basic for Applications

232.43kb.

18 12 2014
1 стр.


Лабораторная работа №1 Изучение автоматической телеграфной станции ат-пс-пд лабораторная работа №2 и зучение телеграфного коммутационного сервера «Вектор-2000»

Рецензент – зам начальника Гомельской дистанции сигнализации и связи Белорусской железной дороги В. И. Прокопюк

822.36kb.

29 09 2014
3 стр.


Лабораторная работа №1 по курсу "Информационная безопасность" Лабораторная работа №1

Простейшей и в то же время наиболее надежной из всех схем шифрования является так называемая схема однократного использования (рис. 1), изобретение, которое чаще всего связывают с

118.45kb.

10 10 2014
1 стр.


Лабораторная работа №1 «Изучение аэрофотосъёмочной аппаратуры». Аэрофотографическая система и ее основные характеристики. Принципиальная схема аэросъёмочного аппарата. Основные части афа. Назначение афа

Лабораторная работа №2 «Составление технического проекта на производство аэрофотосъемочных работ»

26.07kb.

14 12 2014
1 стр.


Лабораторная работа №5 Анализ операций с ценными бумагами

Лабораторная работа №5 включает 5 заданий. Для выполнения этих заданий необходимо ознакомиться с теоретическим материалом, приведенным к данной лабораторной работе и расположенным

166.96kb.

11 09 2014
1 стр.


Лабораторная работа 9-01 Лабораторная Шонин В. А. работа 9-01 Использование табличной верстки для создания Web-страниц

Целью работы является овладение навыками использования табличной верстки при создании Web-страниц

446.97kb.

12 09 2014
1 стр.


Лабораторная работа n 9 Работа с командами обработки строк

В общем случае цепочечные команды позволяют выполнять действия над блоками памяти

56.65kb.

01 10 2014
1 стр.