Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метвказівки для Астистовой1.doc
Скачиваний:
1
Добавлен:
08.11.2019
Размер:
288.26 Кб
Скачать

2. Створення черг повідомлень.

Для ідентифікації повідомлень можна використати ключі, які генеруються в системі при виклику функції

key _ t ftok(char *filename, char proj);

В якості імені файлу можна задавати ім'я будь-якого існуючого файлу, зокрема, для визначеності можна використати ім'я самої програми.

Для обміну використовуються черги повідомлень. Черга створюється функцією

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgget(key _ t key, int msgflg);

Якщо процесу необхідно створити нову чергу повідомлень, то прапор повинен містити макрос IPC _ CREAT, а також права на читання і запис повідомлень в чергу (0644). При нормальному завершенні функція повертає ідентифікатор черги, у разі помилки повертається значення - 1.

Посилка і прийом повідомлень організовуються при виклику функцій

int msgsnd(int msgid, struct msgbuf *msgp, int msgsz, int msgflg);

та

int msgrcv(int msgid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg).

Перший параметр задає ідентифікатор черги. Другий параметр є покажчиком на повідомлення. Повідомлення є структурою

struct msgbuf \u007B

long mtype; /* тип повідомлення */

char mtext[]; /* покажчик на буфер повідомлення */

}

Параметр msgsz визначає довжину повідомлення. При значенні параметра

msgflg=0 процес може блокуватися до тих пір, поки функція не буде виконана. Параметр msgtyp задає правила вибору повідомлення з черги. При

нульовому значенні параметра з черги витягається найстаріше повідомлення

будь-якого типу. Позитивне значення визначає прийом найстарішого повідомлення вказаного типу.

Видалення черги з системи робиться при виклику функції

int msgctl(int msgid, int cmd, struct msgbuf *msgp);

при значенні параметра cmd рівному IPC _ RMID,третій параметр при цьому встановлюється в значення NULL.

Прикдад виконання завдання

Розглянемо дві програми. Перша виконуватиме роль сервера. Вона створює чергу повідомлень і посилає другій програмі - клієнтові рядок введеного з клавіатури тексту. Для попереднього формування повідомлення створюється структура buf за шаблоном mybuf. За запитом з клавіатури водиться рядок тексту (рядок text).

Далі формується ключ. Початковим рядком для формування ключа служить ім'я файлу з текстом програми "smess.c". Черга повідомлень створюється по отриманому раніше ключу з правами доступу для користувача на читання і запис, для інших дозволено тільки читання з черги.

Після створення черги повідомлень у буфер записується текст введеного раніше повідомлення і встановлюється тип повідомлення. Далі сервер пересилає сформоване повідомлення клієнта і завершує роботу. Трансляція сервера здійснюється по командному рядку cc smess.c - o smess. В результаті компіляції і компонування формується виконуваний файл smess.

/* Сервер роботи з повідомленнями */

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int main()

{

key_t key;

struct mybuf {

long mtype;

char mtext[81];

} ;

struct mybuf buf;

int fd;

char text[81];

int textLen;

printf("Ввести текст\n");

gets(text);

textLen=strlen(text);

if((key=ftok("smess.c",0))==-1 ){

perror("Помилка створення ключа");

return 1;

}

if((fd=msgget(key, IPC_CREAT|0644))==-1) {

perror("Помилка створенняя черги");

return 1;

}

strncpy(buf.mtext, text, textLen);

buf.mtype=1L;

if((fd=msgsnd(fd, &buf, textLen,0))==-1) {

perror("Помилка відправки повідомлення");

return 1;

}

return 0;

}

Програма - клієнт розміщується у файлі cmess.c.

Ця програма використовує для прийому повідомлення буфер buf, аналогічний серверу. Аналогічно серверу в ній по тому ж рядку з ім'ям початкового файлу сервера створюється ключ для доступу до черги. На відміну від сервера використовується існуюча черга, тому при виклику функції msgget() досить визначити лише значення ключа.

Для прийому повідомлення у функції msgrcv() задаються перші два параметри, значення прапорів і режиму можна встановити рівними нулю. Текст отриманого повідомлення виводиться на консоль.

/* Клієнт роботи з повідомленнями */

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int main()

{

key_t key;

struct mybuf {

long mtype;

char mtext[81];

} ;

struct mybuf buf;

int fd;

char text[81];

int textLen;

if((key=ftok("smess.c",0))==-1 ){

perror("Помилка створення ключа");

return 1;

}

if((fd=msgget(key, 0))==-1) {

perror("Помилка створення черги");

return 1;

}

if((fd=msgrcv(fd, &buf, 80, 0, 0))==-1) {

perror("Помилка отримання повідомлення");

return 1;

}

printf("Отримано текст -> %s\n",buf.mtext);

return 0;

}

Програма - клієнт запускається на окремій консолі. Для переходу на нову консоль необхідно натиснути комбінацію клавіш Alt+Fn, де n – номер функціональної клавіші. Після створення консолі на ній робиться звичайна реєстрація користувача. На першій консолі запускається клієнт (командний рядок ./cmess). На другій консолі запускається сервер(./smess).