Главная » Все файлы » Просмотр файлов из архивов » PDF-файлы » sem15 - Сокеты. Мультиплексирование ввода-вывода.

sem15 - Сокеты. Мультиплексирование ввода-вывода. (Мини-учебник с ejudge = Чернокнижка), страница 2

PDF-файл sem15 - Сокеты. Мультиплексирование ввода-вывода. (Мини-учебник с ejudge = Чернокнижка), страница 2 Практика расчётов на ПЭВМ (37201): Книга - 3 семестрsem15 - Сокеты. Мультиплексирование ввода-вывода. (Мини-учебник с ejudge = Чернокнижка) - PDF, страница 2 (37201) - СтудИзба2019-05-08СтудИзба

Описание файла

Файл "sem15 - Сокеты. Мультиплексирование ввода-вывода." внутри архива находится в папке "Мини-учебник с ejudge = Чернокнижка". PDF-файл из архива "Мини-учебник с ejudge = Чернокнижка", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Просмотр PDF-файла онлайн

Текст 2 страницы из PDF

Нас интересует домен PF_INET— протоколы, основанные на IPv4. Параметр type задаёт тип соединения. Нас интересует тип соединения SOCK_STREAM — связь с установлением двунаправленного виртуальногосоединения с надежной доставкой (протокол TCP). Возможен тип соединения SOCK_DGRAM— связь без установления соединения (протокол UDP). Параметр protocol позволяет выбрать один из возможно нескольких протоколов, удовлетворяющих двум первым параметрам. Если здесь передаётся 0, протокол будет выбран автоматически, что рекомендуется вданном случае.Системный вызов socket возвращает номер файлового дескриптора, ассоциированного с новым сокетом. С ним можно выполнять все операции, допустимые для файловых дескрипторов: dup, dup2, close.

В случае ошибки системный вызов socket возвращает -1,а переменная errno содержит код ошибки.Системный вызов bind позволяет привязать сокет к определённому адресу и/или порту.#include <sys/types.h>#include <sys/socket.h>intbind(int fd, struct sockaddr *paddr, int addrlen);Параметр fd — это номер файлового дескриптора сокета. Параметр paddr — указатель на структуру, которая содержит информацию о привязке сокета. Содержимое структуры существенно зависит от коммуникационного домена, задаваемого в системном вызовеsocket. Так, для коммуникационного домена PF_INET должна использоваться структураstruct sockaddr_in, определённая следующим образом:struct sockaddr_in {intunsigned shortstruct in_addr};sin_family;sin_port;sin_addr;Поле sin_family задаёт тип адреса, для коммуникационного домена PF_INET тип адреса должен быть установлен в AF_INET.

Поле sin_port определяет номер порта. Номерпорта должен задаваться в сетевом представлении. Если в качестве номера порта указан 0,ядро назначит номер порта автоматически. Поле sin_addr задаёт адрес привязки сокета.Допустима константа INADDR_ANY, обозначающая, что адрес привязки будет назначен автоматически.4В случае успешного выполнения системный вызов возвращает 0, а при ошибке — -1. Переменная errno устанавливается в код ошибки. Возможные ошибки приведены в таблицениже.EBADFEINVALEACCESENOTSOCKfd не является файловым дескриптором.Сокет уже привязан к некоторому адресу.Запрошен адрес или порт, который может использоваться только привилегированным процессом.Файловый дескриптор не ассоциирован с сокетом.1.3.2 Работа клиентаДальнейшее использование сокетов отличается для сервера и для клиента.

Клиент должен выполнить вызов функции connect.#include <sys/types.h>#include <sys/socket.h>int connect(int fd, const struct sockaddr *paddr, int addrlen);Параметр fd задаёт файловый дескриптор сокета. paddr — адрес структуры, определяющей адрес подсоединения, addrlen задаёт размер структуры paddr. В случае успешного завершения функция возвращает 0, а при ошибке возвращается -1.

Переменная errnoустанавливается в код ошибки. Возможные коды ошибок приведены ниже.EBADFEFAULTENOTSOCKEISCONNECONNREFUSEDETIMEDOUTENETUNREACHEADDRINUSEEINPROGRESSEALREADYEAGAINEAFNOSUPPORTEACCES, EPERMНеверный файловый дескриптор fd.Адрес paddr выходит за пределы адресного пространства процесса.Указанный файловый дескриптор не ассоциирован с сокетом.Соединение уже установлено.Никакой процесс не прослушивает указанный адрес и порт.Тайм-аут при подключении. Возможно сервер слишком загружен.Сеть недоступна.Локальный адрес уже используется.Сокет работает в неблокирующем режиме, а соединение не может быть установлено немедленно.Сокет работает в неблокирующем режиме, и предыдущая попытка соединенияещё не закончилась.Недостаточно ресурсов ядра, чтобы выполнить запрос.Передан неверный тип адреса.Недостаточно прав, чтобы выполнить операцию.Если вызов connect завершился успешно, это значит, что соединение установлено, иможно передавать данные.

Один и тот же файловый дескриптор сокета можно использоватьи для передачи данных, и для приёма данных. Работа с ним аналогична работе с каналом.Данные рассматриваются как поток байтов, причём границы сообщений не сохраняются.1.3.3 Работа сервераСервер сначала должен переключить сокет в режим прослушивания. Для этого используется системный вызов listen.#include <sys/socket.h>5int listen(int fd, int backlog);Параметр fd задаёт номер файлового дескриптора сокета. backlog — максимальныйразмер очереди запросов на подключение. Когда очередь переполняется, клиент, которыйпопытается выполнить подключение, получит ошибку ECONNREFUSED.

Обычное значениедля параметра backlog — 5.Системный вызов возвращает 0 при успешном завершении, -1 — при ошибке. В этомслучае переменная errno содержит код ошибки.Для ожидания подключения сервер должен выполнить функцию accept.#include <sys/types.h>#include <sys/socket.h>int accept(int fd, struct sockaddr *paddr, int *paddrlen);Здесь fd — это файловый дескриптор сокета, который должен быть уже переведён в режим прослушивания.

Функция accept приостанавливает выполнение процесса до тех пор,пока от какого-либо клиента не поступит запрос на подключение. Тогда в структуру, на которую указывает paddr, будет записан адрес компьютера и номер порта, с которого производится подключение, а в переменную по адресу paddrlen будет записан размер структуры,содержащей информацию о подключении. При вызове функции эта переменная уже должнасодержать размер структуры. При работе с коммуникационным доменом PF_INET параметрpaddr должен указывать на структуру типа struct sockaddr_in.В случае успешного выполнения функция возвращает новый файловый дескриптор сокета.

Этот файловый дескриптор уже не находится в состоянии прослушивания и должен использоваться для обмена данными с клиентами. Исходный файловый дескриптор fd остаётся в состоянии прослушивания и может использоваться для ожидания подключения другихклиентов. При ошибке возвращается -1, переменная errno устанавливается в код ошибки.1.3.4 Обмен даннымиРабота с виртуальным каналом полностью аналогична работе с обычным каналом. Длячтения из канала используется системный вызов read, для записи в канал используется системный вызов write. Вызов read приостановит процесс до появления данных от другойстороны соединения, а вызов write может приостановить выполнение процесса, если у ядраполностью заполнилась очередь на передачу.

В простейшей ситуации (соединение в локальной сети, небольшой объём данных) можно предполагать, что write не приостанавливаетпроцесс. Когда соединение закрывается, системный вызов read возвращает 0. Для закрытия сокета, когда он становится ненужным, можно использовать системный вызов close.Как обычно можно создать дескриптор потока по файловому дескриптору сокета с помощью функции fdopen, а затем использовать все средства высокоуровневого ввода-вывода.Если высокоуровневые средства используются и для записи в сокет, и для чтения из сокета,необходимо открыть два разных дескриптора потока, один для записи, другой для чтения, которым при создании передать два разных файловых дескриптора, получив второй дескрипториз файлового дескриптора сокета с помощью dup.1.3.5 Установка режимов работы сокетаС помощью функции setsockopt можно установить режимы работы сокета.6#include <sys/types.h>#include <sys/socket.h>int setsockopt(int fd, int level, int optname,const void *optval, int optlen);fd задаёт файловый дескриптор сокета.

Параметр level определяет, режимы какогоуровня необходимо изменить. Возможно изменить режимы работы как самого сокета (константа SOL_SOCKET), так и протокола, используемого для обмена данными, в этом случаенужно указать номер протокола (например, IPPROTO_TCP). Параметр optname задаёт имяизменяемого параметра, а optval — новое значение. Параметр optlen — размер областипамяти, на которую указывает optval.Из всех возможных режимов работы мы здесь упомянем только один.

По умолчанию, когда заканчивает работу процесс, прослушивавший некоторый порт, в течение нескольких минут система не позволяет другим процессам привязываться к этому порту, возвращая ошибкуEINVAL. Это необходимо для того, чтобы проигнорировать пакеты, адресованные уже завершившемуся процессу, которые, возможно, «задержались» в сети.

Однако это приводит ктому, что серверный процесс нельзя перезапустить сразу после того, как он завершился, чтоочень неудобно при разработке и отладке. Если параметр level установить в SOL_SOCKET,optname установить в SO_REUSEADDR, и значение этого параметра установить в 1, портбудет становиться доступным сразу же после завершения процесса-сервера.1.4 Пример клиентаРассмотрим простейшую программу-клиент, которая открывает соединение на заданныйадрес и порт и посылает текущее время.

После этого программа ожидает получения текущеговремени сервера, печатает его и завершает работу.#include#include#include#include#include#include#include#include<stdio.h><stdlib.h><unistd.h><netdb.h><sys/types.h><sys/socket.h><netinet/in.h><time.h>int main(int argc, char const *argv[]){intport, n, sfd;struct hostent*phe;struct sockaddr_in sin;time_tt;if (argc != 3) {fprintf(stderr, "Too few parameters\n");exit(1);}/* получим адрес компьютера */if (!(phe = gethostbyname(argv[1]))) {fprintf(stderr, "Bad host name: %s\n", argv[1]);7exit(1);}/* прочитаем номер порта */if (sscanf(argv[2], "%d%n", &port, &n) != 1|| argv[2][n] || port <= 0 || port > 65535) {fprintf(stderr, "Bad port number: %s\n", argv[2]);exit(1);}/* создаём сокет */if ((sfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {perror("socket");exit(1);}/* для нашего клиента привязка сокета не важна,поэтому bind пропускаем *//* устанавливаем адрес подключения */sin.sin_family = AF_INET;sin.sin_port = htons(port);memcpy(&sin.sin_addr, phe->h_addr_list[0], sizeof(sin.sin_addr));/* подсоединяемся к серверу */if (connect(sfd, (struct sockaddr*) &sin, sizeof(sin)) < 0) {perror("connect");exit(1);}/* отсылаем текущее время */t = time(0);t = htonl(t);/* желательно проверять результат write */write(sfd, &t, sizeof(t));/* считываем время сервера */if (read(sfd, &t, sizeof(t)) != sizeof(t)) {fprintf(stderr, "read failed\n");} else {printf("Server time: %s", ctime(&t));}/* закрываем сокет */close(sfd);return 0;}1.5 Пример сервераВ качестве программы-сервера рассмотрим программу, которая ожидает подключенияот клиента и считывает время клиента.

Текущее время сервера пересылается клиенту. После подключения клиента работа с клиентом ведётся в отдельном процессе. Это позволяетпараллельно обслуживать несколько клиентов и принимать новые запросы.#include <stdio.h>#include <stdlib.h>8#include#include#include#include#include#include#include#include<unistd.h><netdb.h><sys/types.h><sys/socket.h><netinet/in.h><time.h><sys/wait.h><arpa/inet.h>int main(int argc, char const *argv[]){intlfd, n, port, afd, alen, sopt, pid;struct sockaddr_in baddr, aaddr;time_tct, st;if (argc != 2) {fprintf(stderr, "Too few parameters\n");exit(1);}/* прочитаем номер порта */if (sscanf(argv[1], "%d%n", &port, &n) != 1|| argv[1][n] || port <= 0 || port > 65535) {fprintf(stderr, "Bad port number: %s\n", argv[2]);exit(1);}/* создаём сокет */if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {perror("socket");exit(1);}/* задаём режим сокета */sopt = 1;if (setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&sopt,sizeof(sopt))< 0){perror("setsockopt");exit(1);}/* задаём адрес сокета */baddr.sin_family = AF_INET;baddr.sin_port = htons(port);baddr.sin_addr.s_addr = INADDR_ANY;/* привязываем сокет */if (bind(lfd, (struct sockaddr *) &baddr, sizeof(baddr)) < 0) {perror("bind");exit(1);}/* включаем режим прослушивания */if (listen(lfd, 5) < 0) {perror("listen");exit(1);}while (1) {9/* хороним <<зомби>> */while (waitpid(-1, NULL, WNOHANG) > 0);/* ожидаем подключения */alen = sizeof(aaddr);if ((afd = accept(lfd, (struct sockaddr*) &aaddr, &alen)) < 0) {perror("accept");exit(1);}/* запросы клиентов будем обслуживать в другом процессе */if ((pid = fork()) < 0) {perror("fork");} else if (!pid) {close(lfd);/* печатаем информацию о подключении */printf("%d: Connection from %s:%d accepted.\n", getpid(),inet_ntoa(aaddr.sin_addr), ntohs(aaddr.sin_port));if (read(afd, &ct, sizeof(ct)) != sizeof(st)) {fprintf(stderr, "read error\n");} else {/* печатаем время клиента и сервера */ct = ntohl(ct);st = time(0);printf("%d: Client time %lu, server time %lu\n",getpid(), ct, st);st = htonl(st);/* желательно проверять результат write */write(afd, &st, sizeof(st));}close(afd);_exit(0);}close(afd);}return 0;}2Мультиплексирование ввода/выводаВ программе может возникнуть необходимость выполнять операции одновременно снесколькими файловыми дескрипторами.

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