создать поток из функции потока; ждать нажатия клавиши; установить флаг завершения потока; ждать завершения потока; закрыть очередь сообщений; удалить очередь сообщений;
}
Шаблон программы 2:
объявить флаг завершения потока; объявить идентификатор очереди сообщений; функция потока()
{
объявить буфер; пока (флаг завершения потока не установлен)
{
очистить буфер сообщения; принять сообщение из очереди сообщений в буфер; вывести сообщение на экран;
}
}
основная программа()
{
объявить идентификатор потока; создать (или открыть, если существует) очередь сообщений; создать поток из функции потока; ждать нажатия клавиши; установить флаг завершения потока; ждать завершения потока; закрыть очередь сообщений; удалить очередь сообщений;
}
26
Вопросы для самопроверки
1.Какие программные интерфейсы для работы с очередями сообщений существуют?
2.Дайте сравнительную характеристику программных интерфейсов очередей сообщений.
3.Каким образом проверить наличие сообщений в очереди без блокирования процессов?
4.Каким образом проверить наличие сообщений в очереди с определенной периодичностью?
5.Как осуществить передачу и прием оповещения от очереди о появлении нового сообщения?
6.Каким образом можно менять размер сообщений и количество сообщений в очереди?
27
8. ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ ЧЕРЕЗ СОКЕТЫ
Цель работы – знакомство студентов с механизмом взаимодействия удаленных процессов – сокетами – и с системными вызовами, обеспечивающими установление соединения, разъединение, а также передачу и прием данных.
Общие сведения
Сокеты представляют собой программный интерфейс, который предоставляется операционной системой для взаимодействия удаленных процессов.
В зависимости от выбираемых параметров сокеты могут поддерживать локальные соединения, протоколы Интернета, протоколы 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,
28
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 – флаги, описывающие особенности приема.
Указания к выполнению работы
Написать комплект из двух программ, одна из которых выполняет функции сервера, а вторая – функции клиента.
Клиент после установления соединения с сервером посылает ему запросы.
Сервер принимает запросы, обрабатывает их и отправляет ответы клиенту. Функцию обработки следует выбрать самостоятельно.
Клиент принимает ответы и выводит их на экран.
Шаблон программы-сервера:
объявить идентификатор «слушающего» сокета; объявить идентификатор сокета для работы с клиентом; объявить идентификатор очереди запросов на обработку; объявить идентификатор очереди ответов на передачу; объявить флаг завершения потока приема запросов; объявить флаг завершения потока обработки запросов;
29
объявить флаг завершения потока передачи ответов; объявить флаг завершения потока ожидания соединений; функция приема запросов()
{
пока (флаг завершения потока приема не установлен)
{
принять запрос из сокета; положить запрос в очередь на обработку;
}
}
функция обработки запросов()
{
пока (флаг завершения потока обработки не установлен)
{
прочитать запрос из очереди на обработку; обработать запрос и сформировать ответ; положить ответ в очередь на передачу;
}
}
функция передачи ответов()
{
пока (флаг завершения потока передачи не установлен)
{
прочитать ответ из очереди на передачу; передать ответ в сокет;
}
}
функция ожидания соединений()
{
пока (флаг завершения потока ожидания соединений не установлен)
{
прием соединения от клиента; если соединение принято
{
создать поток приема запросов; создать поток обработки запросов;
30