Перейти на главную страницу
Для использования функций WinSock в программе на языке C необходимо включить заголовочный файл winsock2.h:
#include
и указать в свойствах сборки (линковки) программы библиотеку ws2_32.lib (Project >Properties >Configuration Properties >Linker >Input: Additional Dependencies).
if (WSAStartup (MAKEWORD(2,1), &WSAData;) != 0)
{
printf ("WSAStartup faild. Error: %d", WSAGetLastError ());
}
На следующем рисунке изображена последовательность вызовов при реализации клиента и сервера:
int WinSocket;
if ((WinSocket = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf ("Allocating socket failed. Error: %d", WSAGetLastError ());
}
Константа AF_INET указывает, что мы используем сокеты на основе протокола TCP/IP c адресами формата протокола IP 4-ой версии (т.е. привычный нам IP-адрес формата xxx.xxx.xxx.xxx). Константа SOCK_STREAM указывает, что мы используем протокол надежной доставки TCP.
#define PORTNUM 1024
// Укажем параметры локальной части сокета
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 ());
return FALSE;
}
Структура SOCKADDR_IN служит для указания адресной информации сокета. В качестве адреса привязки локальной части мы выбрали все адреса, которые присвоены сетевым интерфейсам компьютера. Если мы хотим привязать к конкретному адреса, например к адресу обратной петли – 127.0.0.1, то нам необходимо использовать функцию inet_addr:
// одновременно будет принят только 1 запрос
#define MAX_PENDING_CONNECTS 1
if (listen (WinSocket, MAX_PENDING_CONNECTS) == SOCKET_ERROR)
{
printf ("Listening to the client failed. Error: %d", WSAGetLastError ());
return FALSE;
}
printf("Waiting connect from client.\n");
accept_sin_len = sizeof (accept_sin);
// Ждем входящего соединения от клиента
ClientSock = accept (WinSocket, (struct sockaddr *) &accept;_sin, (int *) &accept;_sin_len);
{
printf ("Accepting connection with client failed. Error: %d", WSAGetLastError ());
}
Функция accept ждет входящего соединения от клиента, и, после удачного подключения, создает еще один сокет (возвращается в качестве результата выполнения функции), который связан исключительно с клиентом, для которого было установлено соединение. Полученный сокет можно передать отдельному потоку для выполнения операций ввода/вывода с клиентом, а основной поток может еще раз вызвать функцию accept, которая ожидает соединения от клиента.
int recv(SOCKET s, char* buf, int len, int flags);
Параметры:
s |
Сокет |
buf |
Указатель на буфер, в который будут помещены данные |
len |
Размер буфера в байтах |
flags |
Флаги, в нашем случае укажем 0 |
результат функции |
|
В случае, если на данный момент нету доступных данных для чтения из сокета, функция recv не возвращает управления, пока не будет доступен и прочитан хотя бы один байт. Следует знать (!!!!), что функция recv может поместить в буфер меньшее число байт, чем указано в параметре len, это может быть обусловлено тем, что на данный момент нет данных в объеме, указанном в параметре len, либо могут существовать иные причины. Поэтому если мы намереваемся прочитать некоторое фиксированное число байт из сокета, мы должны проверять результат функции recv и повторить запрос на чтение, чтобы дочитать остаток данных, если число прочитанных байт оказалось меньше ожидаемого нами.
int send(SOCKET s, const char* buf, int len, int flags);
Параметры:
s |
Сокет |
buf |
Указатель на буфер, данные из которого будут переданы в сокет |
len |
Размер данных для передачи по сокту |
flags |
Флаги, в нашем случае укажем 0 |
результат функции |
|
closesocket (WinSocket);
struct SOCKADDR_IN remote_sin;
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());
}
remote_sin.sin_addr.S_un.S_addr = *((long *)(he->h_addr));
{
printf ("Connecting to the server failed. Error: %d", WSAGetLastError ());
return FALSE;
}
Передача данных между клиентом и сервером должна осуществляться с использованием сокетов TCP/IP. Для каждого подключения клиента сервер должен создавать отдельный поток, в котором будет выполняться обработка запроса пользователя. Из этого требования следует, что сервер должен корректно работать с несколькими подключенными клиентами. Логика чтения/записи данных из сокета должна корректно обрабатывать неполное чтение/запись из сокета (т.е. число прочитанных/записанных байт может отличаться от значения, указанного в параметре len), так же нужно корректно обрабатывать нулевой результат функции recv.
Данные, передаваемые через сокет, должны быть размещены в буфере приема/отправки в формате, оптимальном для обработки процессором, т.е. если в задании речь идет об обработке:
Калькулятор, работающий с комплексными числами с плавающей точкой, и реализующий следующие операции: сложение, умножение, деление и вычитание. Реализовать обработку ошибок: деление на ноль.
Виртуальная гадалка: в ответ на запрос пользователя должна возвращаться фраза с "предсказанием". Ограничиться набором 10-20 фраз. Реализовать обработку ошибок: ошибка должна возникать случайным образом и означает, что гадалка не знает ответ.
На вход подается массив чисел, программа случайным образом перемешивает числа и выводит результат на экран. Реализовать обработку ошибок: отрицательное число элементов.
Англо-русский словарь: передается слово на английском языке – возвращается его перевод. Ограничиться набором из 10 – 20 слов. Реализовать обработку ошибок: отсутствие слова в словаре.
Определение високосного года: на входе подается год, на выходе булево значение результата. Реализовать обработку ошибок: неверное значение года (напр., отрицательный год)
Генератор последовательности случайных чисел: на входе подается максимальное значение случайного числа и число элементов – на выходе массив полученных чисел. Реализовать обработку ошибок: отрицательное число элементов.
см. вариант 22.
Программа преобразования входной строки в кодировку BASE64 и обратно. Полная спецификация BASE64 содержится в RFC 1421 и RFC 2045.
Для того, чтобы преобразовать данные в BASE64 , первый байт помещается в самые старшие восемь бит 24-битного буфера, следующие в средние восемь и третий в младшие значащие восемь бит. Если кодируется менее чем три байта, то соответствующие биты буфера устанавливаются в ноль. Далее каждые шесть бит буфера, начиная с самых старших, используются как индексы строки «ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/» и её символы, на которые указывают индексы, помещаются в выходную строку. Если кодируются только один или два байта, используются только первые два или три символа строки и выходная строка дополняется двумя или одним символами «=». Это предотвращает добавление дополнительных битов к восстановленным данным. Процесс повторяется над оставшимися входными данными.
Вариант 9
Операции со множествами целых чисел: объединение, пересечение, разность.
Умножение матриц: на входе массивы произвольных размерностей (k,m) и (i,j). Реализовать обработку ошибок: невозможность перемножения матриц вследствие несовпадения размерностей.
Замена вхождения одной последовательности в строке символов на другую последовательность символов. Реализовать обработку ошибок: искомый шаблон не найден.
Поиск числа в целочисленном массиве. Реализовать обработку ошибок: искомое число не найдено.
Замена порядка символов во входной строке на обратный.
Генерация последовательности Фибоначчи: на входе начальные параметры последовательности F0 и F1 и длина ряда. Формула ряда следующая: Fn = Fn-1 + Fn-2
Решение линейного уравнения вида y = a*x + b. Входные параметры: a и b и у. На выходе найденное значение x. Реализовать обработку ошибок: значение параметра a = 0.
Игра "Угадай число": программа «загадывает» число, пользователь пытается угадать это число, программа сообщает, что либо число угадано, либо больше или меньше загаданное число относительно числа, указанного пользователем. Если пользователь заново начинает игру, то программа загадывает новое число.
Генерации монотонной последовательности простых чисел, начиная с 1. Программе указывается число чисел в последовательности. Реализовать обработку ошибок: отрицательное число элементов.
Нахождение корней квадратного уравнения a*x2 + b*x + c = 0. Реализовать обработку ошибок: отсутствие решения в действительных числах.
Генерации геометрической прогрессии: на входе начальный член b0 и число q (знаменатель геометрической прогрессии) и число генерируемых членов. Проверка на ошибки: начальный член должен быть отличен от нуля.
Интерфейс хеш-функции (или, иначе говоря, цифровой подписи):
Указание: для простоты реализации рекомендуется выбрать в качестве хеш-значения беззнаковое длинное целое (т.е. unsigned long int).
Решение системы линейных уравнений вида:
a11x1 + a12x2 = b1
a21x1 + a22x2 = b2
На вход подается матрица A с коэффициентами aij и вектор B с коэффициентами bi; на выходе – вектор Х, содержащий найденные значения xi. Реализовать проверку на ошибки: отсутствие решения.
Вариант 22
Векторная арифметика: сложение, вычитание, скалярное произведение векторов. Реализовать проверку на ошибки: несовпадение размерностей операндов.
Получение производной многочлена следующего вида
Подсчета частоты встречаемости символов в текстовой строке: на вход подается текстовая строка (ASCII-8, т.е. 8-битные строки), на выходе массив частот.
Разбор текстовой строки, содержащей дату и время. Входная строка может иметь следующие форматы:
Проверка принадлежности точки вещественной плоскости с координатами (X1, Y1) к окружности, заданной координатами центра (X2, Y2) и радиусом R. Реализовать проверку на ошибки: отрицательный радиус.
Для каждого целого положительного числа N существует его представление в виде произведения k взаимно простых сомножителей pi с показателем степени ni ≥ 1:
Такое представление единственно, с точностью до порядка следования сомножителей. Если, например, положить pi > pj, для i > j, тогда такое разложение становится полностью определенным единственным образом.
Таким образом, необходимо реализовать программу разложения числа на простые множители. На вход подается число N, на выходе – разложение числа на сомножители согласно приведенной выше формуле.
Реализовать проверку на ошибки: N – отрицательное или нулевое число.
Построение гистограммы. На вход подается массив целых чисел, начало отсчета интервалов и размер интервала. Программа считает число попавших чисел в каждый из интервалов и выводит на экран эти значения. Реализовать проверку на ошибки: отрицательное число элементов, отрицательный или нулевой размер интервала.
Реализовать программу генерации последовательность чисел на основании следующего алгоритма. Имеется некоторое число K (т.н. модуль) и некоторое начальное значение отличное от нуля. Тогда
, где mod – остаток от деления. Для некоторого значения i полученное значение
будет совпадать с начальным значением, т.е.
– это служит признаком конца алгоритма. Таким образом, на вход подаются входные параметры K и
. На выходе – массив, содержащий полученную последовательность. Реализовать проверку на ошибки: модуль меньше 2, начальное значение меньше 1.
Платформа Windows предоставляет программисту еще один механизм взаимодействия процессов – сокеты, которые позволяют образовать дуплексный канал как между процессами как в пределах
10 10 2014
1 стр.
Лабораторная работа Выполнение расчетов с использованием программирования в среде Visual Basic for Applications
18 12 2014
1 стр.
Рецензент – зам начальника Гомельской дистанции сигнализации и связи Белорусской железной дороги В. И. Прокопюк
29 09 2014
3 стр.
Простейшей и в то же время наиболее надежной из всех схем шифрования является так называемая схема однократного использования (рис. 1), изобретение, которое чаще всего связывают с
10 10 2014
1 стр.
Лабораторная работа №2 «Составление технического проекта на производство аэрофотосъемочных работ»
14 12 2014
1 стр.
Лабораторная работа №5 включает 5 заданий. Для выполнения этих заданий необходимо ознакомиться с теоретическим материалом, приведенным к данной лабораторной работе и расположенным
11 09 2014
1 стр.
Целью работы является овладение навыками использования табличной верстки при создании Web-страниц
12 09 2014
1 стр.
В общем случае цепочечные команды позволяют выполнять действия над блоками памяти
01 10 2014
1 стр.