Книга: Основы программирования в Linux
Пересмотр функций клиента
Пересмотр функций клиента
Теперь нужно внести изменения в клиентские функции.
1. Когда клиент стартует, ему нужно найти идентификаторы серверной и клиентской очередей. Клиент не создает очереди. Если сервер не работает, эта функция завершится аварийно, поскольку не существует очередей сообщений.
int client starting() {
#if DEBUG_TRACE
printf("%d :- client_startingn", getpid());
#endif
serv_qid = msgget((key_t)SERVER_MQUEUE, 0666);
if (serv_qid == -1) return(0);
cli_qid = msgget((key_t)CLIENT_MQUEUE, 0666);
if (cli_qid == -1) return(0);
return(1);
}
2. Как и в случае сервера, когда клиент завершает работу, вы задаете некорректные значения глобальных переменных. Это позволит выявить ошибки при попытке клиента отправлять сообщения после вызова функции client_ending
.
void client_ending() {
#if DEBUG_TRACE
printf("%d :- client_ending()n", getpid());
#endif
serv_qid = -1;
cli_qid = -1;
}
3. Для отправки сообщения серверу сохраните данные в своей структуре. Учтите, что вы должны задать ключ сообщения. Поскольку 0 — недопустимое значение для ключа, незаданный ключ означает, что он принимает (очевидно) случайное значение, поэтому иногда эта функция может возвращать ошибку, если значение оказывается нулевым.
int send_mess_to_server(message_db_t mess_to_send) {
struct msg_passed my_msg;
#if DEBUG_TRACE
printf("%d send_mess_to_server()n", getpid());
#endif
my_msg.real_message = mess_to_send;
my_msg.msg_key = mess_to_send.client_pid;
if (msgsnd(serv_qid, (void *)&my_msg, sizeof(mess_to_send) , 0) == -1) {
perror("Message send failed");
return(0);
}
return(1);
}
4. При получении сообщения от сервера клиент использует ID процесса для получения только сообщений, адресованных ему, пропуская сообщения, предназначенные другим клиентам.
int read_resp_from_server(message_db_t *rec_ptr) {
struct msg_passed mymsg;
#if DEBUG_TRACE
printf("%d :- read_resp_from_server()n", getpid());
#endif
if (msgrcv(cli_qid, (void *)&my_msg, sizeof(*rec_ptr), getpid(), 0) == -1) {
return(0);
}
*rec_ptr = my_msg.real_message;
return(1);
}
5. Для сохранения совместимости с файлом pipe_imp.c необходимо объявить четыре дополнительные функции. Но в вашей программе они будут пустыми. Операции, которые они реализовывали в случае применения каналов, больше не нужны.
int start_resp_to_client(const message_db_t mess_to_send) {
return(1);
}
void end_resp_to_client(void) {}
int start_resp_from_server(void) {
return(1);
}
void end_resp_from_server(void) {}
Теперь вы можете просто запустить сервер, выполняющий в фоновом режиме реальное сохранение и извлечение данных, и затем выполнить клиентское приложение для подключения к серверу с помощью сообщений.
Все, что вы должны сделать, — это заменить интерфейсные функции из главы 11 другой реализацией, применяющей очереди сообщений. Преобразование приложения для использования очередей сообщений показывает мощь этого средства IPC, т.к. вам требуется меньше функций, чем в случае применения каналов, и даже эти необходимые функции гораздо проще, чем в предыдущей версии приложения.
- Пересмотр лексического анализа
- Пересмотр функций сервера
- XSLT на стороне клиента
- 8.7. Свойства и методы функций и конструктор Function
- Аватар идеального клиента
- Определение версии клиента
- Снятие ответственности с клиента
- Приложение 21 Образец должностной инструкции начальника отдела по работе с сетевыми клиентами
- 4. Стадии бизнес-процесса взаимодействия с клиентами
- Скрипт «Опрос об удовлетворенности клиента после сделки»
- Скрипт «Обработка входящего звонка от потенциального клиента»
- Вызовы функций