Главная » Просмотр файлов » Варианты заданий

Варианты заданий (1114804), страница 3

Файл №1114804 Варианты заданий (Варианты заданий) 3 страницаВарианты заданий (1114804) страница 32019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Если вызов socket() вернул значение −1, это свидетельствует о происшедшей ошибке. Программа обязательно должна корректно обрабатывать такую ситуацию.132.3Мультиплексирование ввода-выводаПосле того, как вызов accept() успешно отработает в первый раз, в вашейпрограмме появятся два файловых дескриптора, требующих внимания.Это слушающий сокет и сокет, полученный в результате вызова accept()(сокет клиента). На слушающий сокет могут поступить новые запросы, которые необходимо принимать вызовом accept(); в то же время на сокетклиента могут поступить данные, переданные клиентом, которые необходимо прочитать с помощью вызова read().

Какое из этих событий произойдетраньше, неизвестно.Более того, в программе могут быть и другие источники событий. Так,клиентов, скорее всего, будет больше одного. Кроме того, для реализацииуправления сервером нам, возможно, потребуется организовать диалог спользователем, запустившим сервер, для чего необходима возможность обработки данных, поступающих со стандартного ввода программы-сервера.2.3.1Методы организации многопользовательского сервераСуществует несколько подходов к организации программ, работающих снесколькими источниками событий. Самый простой (и некорректный) изних состоит в организации циклического опроса всех имеющихся источников событий. Так, все имеющиеся сокеты можно перевести в так называемый неблокирующий режим, в котором все системные вызовы, относящиесяк таким сокетам, которые не могут быть исполнены без блокирования выполнения процесса, будут возвращать управление сразу же, сигнализируяоб ошибке (в частности, вызов accept(), будучи вызванным в отсутствиенеобработанного запроса на соединение, немедленно вернет −1).Этот способ имеет фундаментальный неустранимый недостаток, заключающийся в наличии так называемого активного ожидания.

Действительно, даже если не происходит никаких событий, требующих обработки,программа-сервер будет вновь и вновь опрашивать имеющиеся дескрипторы, впустую занимая процессорное время. Естественно, пользоваться таким методом ни в коем случае не следует.Второй вариант организации многопользовательского сервера, о котором, в частности, рассказывается в основном курсе лекций “Системное программное обеспечение” в III семестре, основан на создании отдельного процесса для работы с каждым источником событий. В этом случае послекаждого вызова accept() немедленно выполняется вызов fork(), порождающий новый процесс, и родительский процесс возвращается к обработке входящих запросов на соединение, в то время как дочерний процесс14обслуживает клиента, используя полученный от accept() дескриптор.

Подробно этот механизм рассмотрен в книге [2].Такой вариант идеально подходит для случая, когда каждый клиентобслуживается отдельно от остальных и не имеет с ними никакой связи.Однако для случая многопользовательской игры, которая проходит в общем игровом пространстве, такой способ подходит заметно хуже, посколькувлечет активное использование разделяемой памяти и семафоров, что самопо себе усложняет программу3 .Третий способ называется мультиплексированием ввода-вывода иможет быть осуществлен с помощью системных вызовов select()или poll()4.

В дальнейшем мы ограничимся рассмотрением функцииselect(). При желании читатель может освоить функцию poll() самостоятельно, прибегнув к литературе [3] и команде man.2.3.2Вызов select()Системный вызов select() предназначен для использования в ситуации,когда необходимо организовать работу с несколькими файловыми дескрипторами, не имея a priori информации о том, какой из дескрипторов первымпотребует внимания программы.

Кроме того, возможно, требуется отслеживание некоторых событий по времени (например, тайм-аутов на сетевыхсоединениях).Прототип вызова select() выглядит следующим образом:#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int n, fd_setfd_setfd_setstruct*readfds,*writefds,*exceptfds,timeval *timeout);Параметры readfds, writefds и exceptfds обозначают множества файловых дескрипторов, для которых нас интересует, соответственно, возмож3Тем не менее, построить сервер таким образом вполне возможно. Несмотря на сложности, связанные с использованием разделяемой памяти, это может быть интересно в качестве упражнения.4Вообще говоря, select() и poll() предназначены для одних и тех же действий. select() несколькопроще в работе, poll() несколько более универсален.

В некоторых системах ядро реализует только одинвариант интерфейса, при этом второй эмулируется через него в виде библиотечной функции. Так,в системе Solaris присутствует системный вызов poll(), а select() является библиотечной функцией.Кроме того, в некоторых современных системах присутствует также вызов kqueue(), реализующийальтернативный подход к выборке события.15ность немедленного чтения, возможность немедленной записи и наличиеисключительной ситуации. Параметр n указывает, какое количество элементов в этих множествах является значащим.

Этот параметр необходимоустановить равным max_d+1, где max_d – максимальный номер дескриптора среди подлежищих обработке. Наконец, параметр timeout задает промежуток времени, спустя который следует вернуть управление, даже еслиникаких событий, связанных с дескрипторами, не произошло.Объект “множество дескрипторов” задается переменной типа fd_set.Внутренняя реализация переменных этого типа нас, вообще говоря, не интересует5. Для работы с переменными этого типа система предоставляет внаше распоряжение следующие макросы:FD_ZERO(fd_set *set);/*FD_CLR(int fd, fd_set *set);/*FD_SET(int fd, fd_set *set);/*FD_ISSET(int fd, fd_set *set);/*очистить множество */убрать дескриптор из мн-ва */добавить дескриптор к мн-ву */входит ли дескр-р в мн-во? */В рассматриваемой задаче объемы передаваемых по сети данных сравнительно незначительны, что позволяет предполагать, что системные вызовы, осуществляющие запись в сокеты, никогда не будут блокироватьпрограмму-сервер.

Также можно считать, что на сокетах никогда не произойдут исключительные ситуации. Таким образом, аргументы writefds иexceptfds можно не использовать (вместо них передавать вызову select()нулевые указатели).В простейшей версии программы-сервера также нет необходимости виспользовании параметра timeout6. Поэтому можно передать нулевой указатель и в качестве пятого параметра вызова. На всякий случай отметим, чтоструктура timeval имеет два поля типа long. Поле tv_sec задает количество секунд,поле tv_usec - количество микросекунд (миллионных долей секунды).Вызов select() изменяет все переданные ему по указателюаргументы, так что перед каждым обращением к нему аргументыдолжны быть сформированы заново.Вызов select() возвращает −1 в случае возникновения ошибки. Учтите,что, если ваша программа обрабатывает те или иные сигналы, вызов select() можетвернуть −1 в случае, если его выполнение было прервано пришедшим сигналом.

Приэтом значением переменной errno будет EINTR, что свидетельствует о нормальном ходе событий. Вы можете не учитывать данный комментарий, если ваша программа не5Для различных систем она может оказаться разной.Необходимость использования этого параметра возникает при выполнении некоторых дополнительных задач.616перехватывает никаких сигналов. Вызов возвращает значение 0 в случае, еслипричиной выхода из вызова стало наступление заданного таймаута. Есливызов возвратил положительное число, оно означает количество дескрипторов, для которых произошло какое-то событие.После возврата из вызова select() переданные ему переменные типаfd_set оказываются модифицированы.

Если при входе в вызов эти множества содержали дескрипторы, относительно которых нас интересует информация о событиях, то по окончании вызова эти же множества содержатдескрипторы, на которых событие реально произошло (например, по сетиприбыли данные, которые могут быть считаны).Таким образом, работу с вызовом select() можно построить по следующей схеме (считаем, что номер слушающего сокета по-прежнему хранитсяв переменной ls; как хранить дескрипторы клиентских сокетов, читателюпредлагается решить самостоятельно):for(;;) { /* главный цикл */fd_set readfds;int max_d = ls;/* изначально полагаем, что максимальным являетсяномер слушающего сокета */FD_ZERO(&readfds); /* очищаем множество */FD_SET(ls, &readfds);/* вводим в множестводескриптор слушающего сокета */int fd;/* организуем цикл по сокетам клиентов */for(fd=/*дескриптор первого клиента*/ ;/*клиенты еще не исчерпаны?*/;fd=/*дескриптор следующего клиента*/) {/* здесь fd - очередной клиентский дескриптор *//* вносим его в множество */FD_SET(fd, &readfds);/* проверяем, не больше ли он,нежели текущий максимум */if(fd > max_d) max_d = fd;}int res = select(max_d+1, &readfds, NULL, NULL, NULL);if(res < 1) {/* обработка ошибки, происшедшей в select()’е */}if(FD_ISSET(ls, &readfds)) {17/* пришел новый запрос на соединение *//* здесь его необходимо принятьвызовом accept() и запомнитьдескриптор нового клиента */}/* теперь перебираем все клиентские дескрипторы */for(fd=/*дескриптор первого клиента*/ ;/*клиенты еще не исчерпаны?*/;fd=/*дескриптор следующего клиента*/)if(FD_ISSET(fd, &readfds)) {/* пришли данные от клиента с сокетом fd *//* читаем их вызовом \verb.read().

или\verb.recv(). и обрабатываем */}/* конец главного цикла, можно идти наследующую итерацию */}2.42.4.1Прием и передача данных через сокетыЧтениеЧтение данных из сокета можно произвести обычным вызовом read(), ужезнакомым читателю из курса “Системное программное обеспечение”:#include <unistd.h>size_t read(int fd, void *buf, size_t len);либо специально предназначенным для сокетов вызовом recv():#include <sys/types.h>#include <sys/socket.h>size_t recv(int fd, void *buf, size_t len,unsigned int flags);В обоих случаях fd задает файловый дескриптор (в случае recv() это обязательно должен быть дескриптор сокета); buf указывает на буфер, в который следует поместить прочитанные данные; len сообщает вызову размербуфера, чтобы избежать его переполнения.

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

Тип файла
PDF-файл
Размер
373,54 Kb
Высшее учебное заведение

Список файлов ответов (шпаргалок)

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