Обмен сообщениями и импульсами в ОС QNX. Обмен сообщениями при стандартной организации модели "клиент-сервер", управляемой по запросу

Страницы работы

Содержание работы

Санкт-Петербургский государственный политехнический университет

Факультет технической кибернетики

Кафедра компьютерных систем и программных технологий

ОТЧЁТ

по лабораторной работе

Дисциплина: Системное программное обеспечение

Тема: Обмен сообщениями и импульсами в ОС QNX

Работу выполнил студент группы 4081/1

Преподаватель     Е.  

           подпись                   

Санкт-Петербург

2010

1.  Обмен сообщениями

В работе исследовался обмен сообщениями при стандартной организации модели "клиент-сервер", управляемой по запросу. При такой модели сервер первоначально ждёт сообщения, находясь в состоянии блокировки по приёму (receive-blocked). При получении сообщения сервер переходит в состояние готовности (ready) и становится способен выполнять работу. После обработки сообщения сервер посылает ответ клиенту.

1.png.jpg

Рис. 1.1. Смена состояний сервера

При посылке сообщения клиент переходит из состояния готовности (ready) либо в состояние блокировки по приему (reply-blocked) (сервер принял сообщение и обрабатывает его), либо в состояние блокировки по передаче (send-blocked) (сервер ещё не принял сообщение).

2.png.jpg

Рис. 1.2. Смена состояний клиента

Часто используют многопоточную реализацию с помощью семейства функций thread_pool_*(), при которой каждый из потоков способен обрабатывать сообщения от клиентов. Такая реализация наиболее эффективна в многопроцессорных системах.

3.png.jpg

Рис. 1.3. Обслуживание клиентов различными потоками сервера

Также применяется модель «сервер/субсервер», в которой несколько субсерверов посылают сообщения серверу, но сервер отвечает им только по мере запросов от клиентов. В итоге сообщения клиентов передаются субсерверам, которые выполняют их обработку.

Благодаря такой модели сервер сам не обрабатывает сообщения и может продолжать принимать запросы от клиентов. Модель полезна при использовании распределённых систем.

4.png.jpg

Рис. 1.4. Модель «сервер/субсервер»

1.1.  Передача сообщений между двумя родственными процессами

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

Программа server.c:

#include <sys/neutrino.h>

#include <errno.h>

#include <process.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main (void) {

// Идентификаторы соединения и клиента

int chid, rcvid;

// Счётчик принятых сообщений

int i;

// Приёмный буфер и буфер для ответа

char receive_buf[50], reply_buf[50];

// Создание канала

chid = ChannelCreate(0);  

// Порождение дочерних процессов-клиентов

spawnl(P_NOWAIT, "client", "client", NULL);          

sleep(2);

spawnl(P_NOWAIT, "client", "client", NULL);          

sleep(2);

spawnl(P_NOWAIT, "client", "client", NULL);          

sleep(2);

for (i = 0; i < 3; i++) {

// Принимаем сообщение

rcvid = MsgReceive(chid, &receive_buf, sizeof(receive_buf), NULL);

// Если не импульс, обрабатываем сообщение

if (rcvid) {

// Выведем текст принятого сообщения

printf("SERVER: message from client \"%s\"\n", &receive_buf );

// Запишем в буфер ответа сообщение для клиента

sprintf(reply_buf, "Reply from server to client", rcvid);

// Отправим ответ

printf("SERVER: send message to client \"%s\"\n", &reply_buf );

MsgReply(rcvid, EOK, &reply_buf, sizeof(reply_buf));

}

}

// Уничтожаем канал

ChannelDestroy(chid);

return EXIT_SUCCESS;

}

Программа client.c:

#include <sys/neutrino.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main () {

// Идентификатор соединения

int coid;

// Возвращаемое значение MsgSend

int status;

// PID текущего процесса и процесса-сервера

int pid = getpid(), server_pid = getppid();

// Буферы для отправляемого и принимаемого сообщений

char send_buf[50], reply_buf[50];

// Устанавливаем соединение с сервером

coid = ConnectAttach(0, server_pid, 2, 0, 0);

// Запишем в буфер текст сообщения для сервера 

sprintf(send_buf, "Hello from client with PID = %d", pid);

// Отправляем сообщение и принимаем ответ

printf("Client: send message \"%s\"\n", &send_buf );

status = MsgSend(coid,  &send_buf, sizeof(send_buf), &reply_buf, sizeof(reply_buf));

if (status == -1) {

printf("Error of MsgSend\n");

return EXIT_FAILURE;

}

printf("Client: message \"%s\" from server\n", &reply_buf);

// Закрываем соединение

ConnectDetach(coid);

return EXIT_SUCCESS;

}

Использованные функции:

1)  На стороне сервера

#include <sys/neutrino.h>

int ChannelCreate( unsigned flags ); - создание канала

int MsgReceive( int chid,

void * msg,

int bytes,

struct _msg_info * info ); - принятие сообщения

int MsgReply( int rcvid,

int status,

const void* msg,

int size ); - ответ клиенту

2)  На стороне клиента

Похожие материалы

Информация о работе