Книга: Основы программирования в Linux

Пересмотр функций сервера

Пересмотр функций сервера

Сначала нужно обновить серверные функции.

1. Прежде всего, включите необходимые заголовочные файлы, объявите несколько ключей очередей сообщений и структуру для хранения данных сообщения:

#include "cd_data.h"
#include "cliserv.h"
#include <sys/msg.h>
#define SERVER_MQUEUE 1234
#define CLIENT_MQUEUE 4321
struct msg_passed {
 long int msg_key; /* Используется для клиентского pid */
 message_db_t real message;
};

2. Две глобальные переменные хранят идентификаторы двух очередей, возвращаемые функцией msgget:

static int serv_qid = -1;
static int cli_qid = -1;

3. Сделайте сервер ответственным за создание обеих очередей сообщений:

int server starting() {
#if DEBUG_TRACE
 printf("%d :- server_starting()n", getpid());
#endif
 serv_qid = msgget((key_t)SERVER_MQUEUE, 0666 | IPC_CREAT);
 if (serv_qid == -1) return(0);
 cli_qid = msgget((key_t)CLIENT_MQUEUE, 0666 | IPC_CREAT);
 if (cli_qid == -1) return(0);
 return(1);
}

4. За удаление очереди, если она существует, также отвечает сервер. Когда сервер заканчивает работу, вы задаете недопустимые значения вашим глобальным переменным. Это позволит выловить любые ошибки при попытке сервера отправить сообщения после вызова функции server_ending:

void server_ending() {
#if DEBUG_TRACE
 printf("%d :- server_ending()n", getpid());
#endif
 (void)msgctl(serv_qid, IPC_RMID, 0);
 (void)msgctl(cli_qid, IPC_RMID, 0);
 servqid = -1;
 cliqid = -1;
}

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

int read_request_from_client(message_db_t *rec_ptr) {
 struct msg_passed my_msg;
#if DEBUG_TRACE
 printf("%d :- read_request_from_client()n", getpid());
#endif
 if (msgrcv(serv_qid, (void *)&my_msg, sizeof(*rec_ptr), 0, 0) == -1) {
  return(0);
 }
 *rec_ptr = my_msg.real_message;
 return(1);
}

6. При отправке сообщения для его адресации используется ID клиентского процесса, хранящийся в запросе:

int send_resp_to_client(const message_db_t mess_to_send) {
 struct msg_passed my_msg;
#if DEBUG_TRACE
 printf("%d :- send_resp_to_client()n", getpid());
#endif
 my_msg.real_message = mess_to_send;
 my_msg.msg_key = mess_to_send.client_pid;
 if (msgsnd(cli_qid, (void *)&my_msg, sizeof(mess_to_send), 0) == -1) {
  return(0);
 }
 return(1);
}

Оглавление книги


Генерация: 1.605. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз