Материал: metod_ukaz

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

char mtext[1]; /* содержание сообщения */

};

size_t msgsz – размер сообщения;

int msgflg – флаги, описывающие режим работы функции, например, вызов функции без блокировки (IPC_NOWAIT).

Прием сообщений из очереди производится вызовом:

ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);

где:

int msqid – идентификатор очереди;

struct msgbuf *msgp – буфер для приема сообщений;

size_t msgsz – размер сообщения;

long msgtyp – тип сообщения;

int msgflg – флаги, описывающие режим работы функции.

После работы с очередью ее необходимо удалить вызовом:

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

где:

int msqid – идентификатор очереди;

int cmd – команда управления, для удаления IPC_RMID;

struct msqid_ds *buf – буфер для установки и получения информации об очереди, игнорируется в случае команды удаления.

Указания к выполнению работы

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

Студент, который находится в списке группы под нечетным номером, реализует очередь по стандарту SVID.

Студент, который находится в списке группы под четным номером, реализует очередь по стандарту POSIX.

Шаблон программы 1 представлен ниже:

объявить флаг завершения потока;

объявить идентификатор очереди сообщений;

Функция потока()

{

объявить буфер;

пока (флаг завершения потока не установлен)

{

сформировать сообщение в буфере;

записать сообщение из буфера в очередь сообщений;

задержать на время;

}

}

основная программа()

{

объявить идентификатор потока;

создать (или открыть, если существует) очередь сообщений;

создать поток из функции потока;

ждать нажатия клавиши;

установить флаг завершения потока;

ждать завершения потока;

закрыть очередь сообщений;

удалить очередь сообщений;

}

Шаблон программы 2 представлен ниже:

объявить флаг завершения потока;

объявить идентификатор очереди сообщений;

Функция потока()

{

объявить буфер;

пока (флаг завершения потока не установлен)

{

очистить буфер сообщения;

принять сообщение из очереди сообщений в буфер;

вывести сообщение на экран;

}

}

основная программа()

{

объявить идентификатор потока;

создать (или открыть, если существует) очередь сообщений;

создать поток из функции потока;

ждать нажатия клавиши;

установить флаг завершения потока;

ждать завершения потока;

закрыть очередь сообщений;

удалить очередь сообщений;

}

Вопросы для самопроверки

  1. Какие программные интерфейсы для работы с очередями сообщений существуют?

  2. Дайте сравнительную характеристику программных интерфейсов очередей сообщений.

  3. Каким образом обеспечить проверку наличия сообщений в очереди без блокирования процессов?

  4. Каким образом обеспечить проверку наличия сообщений в очереди с определенной периодичностью?

  5. Как осуществить передачу и прием оповещения от очереди о появлении нового сообщения в очереди?

  6. Каким образом можно менять размер сообщений и количество сообщений в очереди?

Раздел 3. Управление коммуникациями в ос

9. Сетевое взаимодействие процессов через сокеты

Цель работы - знакомство студентов с механизмом взаимодействия удаленных процессов – сокетами и с системными вызовами, обеспечивающими установление соединения, разъединение, а также передачу и прием данных.

Общие сведения

Сокеты представляют собой программный интерфейс, который предоставляется операционной системой для взаимодействия удаленных процессов.

В зависимости от выбираемых параметров сокеты могут поддерживать локальные соединения, протоколы Интернет, протоколы Novell, Х.25 и другие.

Сокеты поддерживают обмен сообщениями с установлением соединения (протокол ТСР), обеспечивающий надежную упорядоченную передачу сообщений, и обмен сообщениями без установления соединения (протокол UDP), обеспечивающий ненадежную передачу сообщений, которые могут теряться, и порядок поступления которых может быть нарушен.

Сокет создается следующим вызовом:

int socket(int domain, int type, int protocol),

где:

domain. – определяет тип коммуникационного протокола (Интернет, Novell, Х.25);

type – определяет тип передачи (надежная, ненадежная);

protocol – конкретизация типа коммуникационного протокола.

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

int bind(int s,

struct sockaddr *addr,

socklen_t addrlen),

где:

s – дескриптор сокета;

addr – указатель на структуру, содержащую адрес, к которому привязывается сокет;

addrlen – размер структуры.

Перевод сокета в состояние прослушивания осуществляется вызовом:

int listen(int s, int backlog),

где:

s – дескриптор сокета;

backlog – размер очереди соединений с клиентами.

Прием первого соединения из очереди соединений с клиентами осуществляется вызовом:

int accept(int s,

struct sockaddr *addr,

socklen_t *addrlen),

где:

s – дескриптор слушающего сокета;

addr – указатель на структуру, содержащую адрес клиента;

addrlen – размер структуры.

Установление соединения с сервером осуществляется вызовом:

int connect(int s,

const struct sockaddr *addr,

socklen_t addrlen),

где:

s – дескриптор сокета;

addr – указатель на структуру, содержащую адрес сервера;

addrlen – размер структуры.

Передача данных в сокет осуществляется следующим вызовом:

int send(int s, const void *msg, size_t len, int flags),

где:

s – дескриптор сокета;

msg – адрес буфера, содержащего данные для передачи;

len – размер передаваемых данных;

flags – флаги, описывающие особенности передачи.

Прием данных из сокета производится вызовом:

int recv(int s, void *buf, size_t len, int flags),

где:

s – дескриптор сокета;

buf - адрес буфера, в который принимаются данные;

len – размер буфера;

flags – флаги, описывающие особенности приема.

Чтобы закрыть соединение, необходимо вызвать функцию, которая запрещает прием или передачу (или и то и другое) через сокет:

int shutdown(int socket, int how);

где:

int socket – дескриптор сокета;

int how – способ запрета (прием, передача, прием и передача).

Для передачи данных без установления соединения вызовы функций listen(), accept() и connect() не требуются.

Передача сообщений без установления соединения осуществляется вызовом:

ssize_t sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

где:

int s – дескриптор сокета;

const void *msg – указатель на буфер сообщения;

size_t len – длина сообщения;

int flags – битовая маска, описывающая режим работы функции;

const struct sockaddr *to – структура, описывающая получателя сообщения;

socklen_t tolen – размер структуры.

Прием сообщений без установления соединения осуществляется вызовом:

int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

где:

int s – дескриптор сокета;

void *buf – указатель на буфер сообщения;

size_t len – размер буфера;

int flags – битовая маска, описывающая режим работы функции;

const struct sockaddr *from – структура, описывающая отправителя сообщения;

socklen_t *fromlen – указатель на переменную, содержащую размер структуры.

Перед завершением работы сокет необходимо закрыть вызовом функции:

int close(int fd);

где:

int fd – дескриптор сокета.

Указания к выполнению работы

Написать комплект из двух программ, одна из которых выполняет функции сервера, а вторая выполняет функции клиента.

Клиент после установления соединения с сервером посылает ему запросы.

Сервер принимает запросы, обрабатывает их и отправляет ответы клиенту. Функцию обработки следует выбрать из таблицы.

Клиент принимает ответы и выводит их на экран.

Использовать функции работы с сокетами без блокировки.

В качестве очередей запросов на обработку и передачу использовать типы данных std::vector или std::queue.

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

Студент, который находится в списке группы под четным номером, использует протокол с установлением соединения (TCP).

Студент, который находится в списке группы под нечетным номером, использует протокол без установления соединения (UDP).

Шаблон программы-сервера для случая TCP представлен ниже:

объявить идентификатор «слушающего» сокета;

объявить идентификатор сокета для работы с клиентом;

объявить идентификатор очереди запросов на обработку;

объявить идентификатор очереди ответов на передачу;

объявить флаг завершения потока приема запросов;

объявить флаг завершения потока обработки запросов;

объявить флаг завершения потока передачи ответов;

объявить флаг завершения потока ожидания соединений;

функция приема запросов()

{

пока (флаг завершения потока приема не установлен)

{

принять запрос из сокета;

положить запрос в очередь на обработку;

}

}

функция обработки запросов()

{

пока (флаг завершения потока обработки не установлен)

{

прочитать запрос из очереди на обработку;

обработать запрос и сформировать ответ;

положить ответ в очередь на передачу;

}

}

функция передачи ответов()

{

пока (флаг завершения потока передачи не установлен)

{

прочитать ответ из очереди на передачу;

передать ответ в сокет;

}

}

функция ожидания соединений()

{

пока (флаг завершения потока ожидания соединений не установлен)

{

прием соединения от клиента;

если соединение принято

{

создать поток приема запросов;

создать поток обработки запросов;

создать поток передачи ответов;

завершить работу потока ожидания соединений;

}

}

}

основная программа()

{

объявить идентификатор потока приема запросов;

объявить идентификатор потока обработки запросов;

объявить идентификатор потока передачи ответов;

объявить идентификатор потока ожидания соединений;

создать «слушающий» сокет;

привязать «слушающий» сокет к адресу;

перевести сокет в состояние прослушивания;

создать очередь запросов на обработку;

создать очередь ответов на передачу;

создать поток ожидания соединений;

ждать нажатия клавиши;

установить флаг завершения потока приема запросов;

установить флаг завершения потока обработки запросов;

установить флаг завершения потока передачи ответов;

установить флаг завершения потока ожидания соединений;

ждать завершения потока приема запросов;

ждать завершения потока обработки запросов;

ждать завершения потока передачи ответов;

ждать завершения потока ожидания соединений;

Источник: https://studfile.net/preview/16676187/