Главная » Просмотр файлов » Сетевое программирование в Linux

Сетевое программирование в Linux (1119562), страница 2

Файл №1119562 Сетевое программирование в Linux (Сетевое программирование в Linux) 2 страницаСетевое программирование в Linux (1119562) страница 22019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

По большому счёту, это излишняя предосторожность, поэтому на эти две строки можно смело забить (по крайней мере не нужно пытаться понять, каконо там работает).linger linger_opt = { 1, 0 };setsockopt(s0, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(linger_opt));3.1.3. Приём входящих соединений и функция acceptНаконец-то наступает кульминационный момент в жизни гнезда s0.

Всё, что было написано выше, былонужно ради следующих двух команд:listen(s0, 1);sockaddr_in CliAddr;socklen_t AddrLen;int s1 = accept(s0, (struct sockaddr*) &CliAddr, &AddrLen);Вызвав функцию listen, мы заставляем систему ждать прихода запроса на соединение от клиента. Второйпараметр указывает на требуемое количество подключений — в нашем случае нужен только один клиент. Следует помнить, что эта функция будет ждать вечно, если никто не захочет подключаться к нашему серверу. Но3будем считать, что хоть один юзер догадался выполнить функцию connect, да ещё к тому же угадал номерпорта и IP-адрес нашей станции. Тогда listen завершится, и можно будет выяснить, что же это за юзер —по крайней мере, мы сможем узнать IP-адрес его компьютера и номер порта, на котором он сидит. А делатьэто мы будем так: заведём ещё одну переменную типа sockaddr_in, назвав её CliAddr, и вызовем функциюaccept, передав в качестве первого аргумента дескриптор того гнезда, на которое пришло сообщение, а в качестве второго — указатель на структуру для адреса клиента.

Функция accept занесёт туда все данные о нашемновом клиенте, а её возвращаемое значение — дескриптор гнезда, по которому можно будет предавать клиентуданные.С этого момента установка соединения со стороны сервера считается успешной. Далее про всякие accept’ы,bind’ы и listen’ы можно забыть. Они относятся к инициализационной части программы и далее нам нужнобудет только посылать и принимать данные с помощью функций read/write.

Более того, гнездо s0 теперьможно даже закрыть — оно больше не пригодится. Закрытие гнезда производится функцией close.3.2. Клиентская частьТеперь посмотрим, что в это время происходит на другом конце провода.3.2.1. Получение адреса сервераТот вид соединений, который мы здесь используем (т. е. connection-oriented), предполагает, что сервер сидиттихо и только «слушает». Клиент же, напротив, должен послать запрос на соединение по вполне конкретномуадресу. Но откуда, позвольте спросить, он возьмёт этот адрес? Конечно, может быть так: два человека захотелисыграть по сети, и один из них знает IP-адрес компьютера другого. Тогда всё тривиально: указываем нужныйадрес и подключаемся туда, где нас уже ждут.

Но как быть, когда мы не знаем адреса сервера? Тут разумновоспользоваться функцией gethostbyname, позволяющей по имени сервера определить его адрес. Это эквивалентно тому, как если бы мы стали искать в адресной книге адрес требуемого учреждения (естественно, еслимы знаем, как оно называется).hostent * Host = gethostbyname(HostName);Здесь HostName есть строка с именем сервера.

Среди всех допустимых имён зарезервировано специальноеимя localhost. Если выполняется подключение к localhost, то подключение происходит «к самому себе»,т. е. клиент и сервер должны работать на одном и том же компьютере. С тем же успехом можно вместослова localhost указать IP-адрес 127.0.0.1, также означающий себя самого. Функция gethostbyname возвращаетадрес некоторой структуры типа hostent, у которой есть поле h_addr_list, представляющее собой массивадресов, соответствующих данному серверу.

Мы выберем из этого массива первый элемент и засунем его вструктуру. . . нет, совсем забыл, сначала надо же ещё объявить переменную sockaddr_in SrvAddr, почиститьеё memset’ом, и только потом скопировать адрес. Ну, а про настройку типа адреса и номера порта всё уже былосказано выше — тут ничего нового нет.sockaddr_in SrvAddr;memset(&SrvAddr, 0, sizeof(SrvAddr));SrvAddr.sin_family = AF_INET;SrvAddr.sin_port = htons(Port);memmove(&(SrvAddr.sin_addr.s_addr), Host->h_addr_list[0], 4);3.2.2.

Подключение к серверуТут всё предельно просто. Для начала создадим гнездо — точно также, как и на сервере, а затем вызовемдолгожданный connect:int s0 = socket(AF_INET, SOCK_STREAM, 0);connect(s0, (sockaddr*) &SrvAddr, sizeof(SrvAddr));Вторым параметром передаётся тот самый адрес, которой был получен столь долгим и мучительным путём.Если на другом конце провода нас не ждут, то connect вернёт отрицательное значение. В противном случаеможно считать, что соединение установлено.4.

Сетевой обмен даннымиНастало время разобраться с тем, ради чего мы заварили всю эту кашу с сокетами (надеюсь, пока у читателяв голове подобной каши ещё не возникло). С посылкой данных всё совсем просто: делаем массив, ну, скажем,на 1024 байта (назовём его SendBuf), запихиваем данные в этот массив и вызываем функцию write:4write(s1, SendBuf, 1024 * sizeof(char));Естественно, так выглядит команда посылки со стороны сервера.

Для клиента — почти так же, тольковместо s1 нужно написать s0. А вот с приёмом пакетов дела обстоят несколько хитрее. Часто в сетевых программах (например в играх) нельзя ждать, пока придет очередное сообщение, а нужно выполнять какие-тодругие действия (например, перерисовывать экран). Поэтому имеет смысл воспользоваться функцией select.Она позволяет определить, есть ли у гнезда новые данные, или нет. Кроме того, эта функция умеет ждатьприхода сообщения в течение определённого промежутка времени, и если он проходит, а сообщения всё нет, тофункция завершается.

Эта функция позволяет отслеживать очень маленькие промежутки времени — с точностью до одной микросекунды. Напишем функцию bool CheckMessage(int Socket, char * Buffer), котораябудет проверять, пришло ли сообщение на сокете Socket. Если да, то она возвращает true и «сливает 1024 байтаиз входной трубы сокета» в массив Buffer, а если нет, то просто возвращает false.bool CheckMessage(int Socket, int * Buffer){fd_set DSet;FD_ZERO(&DSet);FD_SET(Socket, &DSet);timeval tv;tv.tv_sec = 0;tv.tv_usec = 10000;if (select(Socket+1, &DSet, 0, 0, &tv) > 0){read(Socket, Buffer, 1024);return true;}else return false;}1секунды данМаксимальный интервал ожидания установлен в 10000 микросекунд, т.

е. если в течение 100ные не появятся, будет выдано значение false. Использовать функцию CheckMessage надо примерно так: послеустановки соединения делаем бесконечный цикл, в котором вызываем эту функцию, и если результат положительный, то обрабатываем данные, иначе — продолжаем цикл.Скажем пару слов о том, что такое fd_set и select. Как уже было сказано, сокет — это дескриптор потокаввода-вывода. В недрах ОС содержится информация по каждому дескриптору, и разработчики предусмотрелимеханизм получения этой информации.

Структура fd_set описывает битовое множество всех дескрипторов.Существует три типа событий, сигнализирующих о состоянии каждого дескриптора:• Есть данные для чтения• Гнездо готово к записи данных• Произошла ошибкаЗа эти три типа событий отвечают второй, третий и четвёртый параметры функции select соответственно.Чтобы получить информацию о каком-либо дескрипторе, нужно установить в соответствующем битовом множестве бит этого дескриптора и вызвать функцию select.

Первый параметр ограничивает максимальный номеринтересующего нас дескриптора плюс один.Нас интересует только информация о данных на чтение, поэтому третий и четвёртый параметры установленыв нули. Последний параметр — это величина таймаута в микросекундах. Функция select будет «прослушивать»указанные дескрипторы в течение этого времени, и, если в каком-либо из выбранных дескрипторов произошлособытие требуемого типа, вернёт положительное число. Чтобы узнать, в каком именно, вообще говоря, нужнопроверить битовое множество DSet, но в нашем случае дескриптор всего один, и проверять ничего не нужно.Если бы таковая проверка была бы необходима, её следовало бы выполнять с помощью макроса FD_ISSET. Болееподробную информацию о select всегда можно посмотреть в справочной системе Linux.5.

Пример программыСтрого говоря, теория изложена в полном объёме. Остаётся немного попрактиковаться и написать какую-нибудь программу. Но чтобы читателю не было скучно, мы кратко изложим на словах её алгоритм, а в качествеработоспособного примера приведём другую программу.55.1. Упражнение: пересылка файла по сетиНапишите самостоятельно программу, пересылающую двоичный файл с одного компьютера на другой.

Длячтения и записи двоичных (т. е. не обязательно текстовых) файлов есть функцииint fread(void * Buffer, int Size, int Count, FILE * F)int fwrite(void * Buffer, int Size, int Count, FILE * F)Пусть файл передаётся от сервера к клиенту. Тогда алгоритм работы будет примерно следующий: сервер вцикле считывает файл кусками (например, по 1024 байта) и отправляет клиенту сообщения такого формата:Размер i-го куска (4 байта)i-й кусок файла (6 1024 байт)Клиент же записывает эти куски последовательно себе на диск в какой-нибудь файл, а после записи очередного куска отправляет подтверждение серверу. Сервер же в это время ждёт подтверждения, и когда оноприходит, посылает очередной кусок файла.

Подтверждения нужны не для того, чтобы гарантировать доставкуданных, а для того, чтобы в сети не произошло «затора» из пакетов. Запись на диск — медленная операция (покрайней мере, медленнее, чем чтение), и может получиться так, что клиент не будет успевать «сливать водуиз трубы-сокета». Для маленьких файлов это будет незаметно, а вот при попытке переслать файл мегабайт надесять могут начаться всякие глюки...5.2. Пример: игра «Быки и коровы»Напомним, что игра состоит в угадывании четырёхзначного числа, загаданного противником, который информирует игрока о количестве точных совпадений, или «быков» (правильная цифра на правильном месте) иколичестве неточных совпадений, или «коров» (правильная цифра не на своём месте).В данном случае клиент и сервер фактически равноправны, поэтому код сервера и клиента отличается толькомеханизмом установки соединения.5.2.1.

Серверная часть#include#include#include#include#include#include#include<signal.h><stdio.h><string.h><stdlib.h><unistd.h><sys/socket.h><netinet/in.h>const int MAX = 64;void SigHandler(int SigID);bool WaitMessage(int Socket, int * Buffer);bool GetAnswer(int N, int GN, int * B, int * C);// Обработчик ошибок гнезда// Функция ожидания данных// Вычисляет количество быков и коровint main(int argc, char * argv[]){printf("Welcome to the game ’Bulls & Cows’.

Характеристики

Список файлов учебной работы

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6392
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее