6.7. Пример программы клиент-сервер

We use cookies. Read the Privacy and Cookie Policy

6.7. Пример программы клиент-сервер

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

Заголовочный файл svmsg.h приведен в листинге 6.7. Мы подключаем наш стандартный заголовочный файл и определяем ключи для каждой из очередей сообщений.

Листинг 6.7. Заголовочный файл svmsg.h для программы клиент-сервер, использующей очереди сообщений

//svmsgcliserv/svmsg.h

1 #include "unpipc.h"

2 #define MQ_KEY1 1234L

3 #define MQ_KEY2 2345L

Функция main для сервера приведена в листинге 6.8. Программа создает обе очереди сообщений, и не беда, если какая-нибудь из них уже существует, потому что мы не указываем флаг IPC_EXCL. Функция server дана в листинге 4.16. Она вызывает наши собственные функции mesgsend и mesgrecv, новые версии которых будут приведены ниже.

Листинг 6.8. Функция main программы-сервера, использующей очереди сообщений

//svmsgcliserv/server_main.с

1  #include "svmsg.h"

2  void server(int, int);

3  int

4  main(int argc, char **argv)

5  {

6   int readid, writeid;

7   readid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT);

8   writeid = Msgget(MQ_KEY2, SVMSG_MODE | IPC_CREAT);

9   server(readid, writeid);

10  exit(0);

11 }

Листинг 6.9. Функция main программы-клиента, использующей очереди сообщений

//svmsgcliserv/client_main.с

1  #include "svmsg.h"

2  void client(int, int);

3  int

4  main(int argc, char **argv)

5  {

6   int readid, writeid;

7   /* assumes server has created the queues */

8   writeid = Msgget(MQ_KEY1, 0);

9   readid = Msgget(MQ_KEY2, 0);

10  client(readid, writeid);

11  /* now we can delete the queues */

12  Msgctl(readid, IPC_RMID. NULL);

13  Msgctl(writeid, IPC_RMID, NULL);

14  exit(0);

15 }

В листинге 6.9 приведен текст функции main программы-клиента. Программа открывает две очереди сообщений и вызывает функцию client из листинга 4.15. Эта функция использует две другие: mesg_send и mesg_recv, которые будут приведены ниже.

И функция client, и функция server используют формат сообщений, изображенный в листинге 4.12. Для передачи и приема сообщений они используют функции mesg_send и mesg_recv. Старые версии этих функций, приведенные в листингах 4.13 и 4.14, вызывали write и read и работали с программными каналами и FIFO, так что нам придется переписать их для использования очередей сообщений. В листингах 6.10 и 6.11 приведены новые версии этих функций. Обратите внимание, что аргументы функций не изменились, поскольку первый целочисленный аргумент может содержать как целочисленный дескриптор программного канала или FIFO, так и целочисленный дескриптор очереди сообщений.

Листинг 6.10. Функция mesg_send, работающая с очередью сообщений System V

//svmsgcliserv/mesg_send.с

1 #include "mesg.h"

2 ssize_t

3 mesg_send(int id, struct mymesg *mptr)

4 {

5  return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0));

6 }

Листинг 6.11. Функция mesg_recv, работающая с очередью сообщений System V

//svmsgcliserv/mesg_recv.с

1 #include "mesg.h"

2 ssize_t

3 mesg_recv(int id, struct mymesg *mptr)

4 {

5  ssize_t n;

6  n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0);

7  mptr->mesg_len = n; /* количество возвращаемых данных */

8  return(n); /* –1 в случае ошибки, 0 – конец файла, иначе – >0 */

9 }

Данный текст является ознакомительным фрагментом.