extern struct sigevent notification;
/* Принимаем сообщение */
int n;
n = mq_receive( msg_queue_id, buff, BUF_LEN, &prio );
if( n < 0 )
{
printf( "Server: message receive error!!!\n" );
return;
}
printf( "Server: message received, length = %d\n", n );
printf( "Message: %s\n", buff );
printf( "Prio: %d\n", prio );
/* Отправляем клиенту уведомление */
strcpy( buff, "OK" );
buff[2] = '\0';
prio = 31;
if( mq_send( msg_queue_id, buff, strlen(buff), prio ) < 0 )
{
printf( "Server: send message error!!!\n" );
return;
}
/* Восстанавливаем диспозицию */
signal( SIGUSR1, sigusr1_handler );
/* Перерегистрируемся */
if( mq_notify( msg_queue_id, ¬ification ) < 0 )
{
printf( "Server: set notify mode queue error!!!\n" );
return;
}
}
Ожидание сообщений от клиентов в программе-сервере реализовано с помощью уведомления процесса о том, что в очередь было помещено сообщение. Если уведомлений не приходило, то программа находится в ожидании и не занимает ресурсов.
Уведомление устанавливается с помощью функции mq_notify(), о помещенном в очередь сообщении сигнализирует посылка пользовательского сигнала, обработка принятого сообщения и ответ клиенту ведется в обработчике сигнала.
Ответные сообщения от сервера посылаются с наивысшим приоритетом 31.
Листинг. 5.2.1. Программа-клиент. msg_client.c.
/*
* Сообщения Posix
* Программа клиента
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <mqueue.h>
int main( int argc, char *argv[] )
{
mqd_t msg_queue_id_rd,
msg_queue_id_wr;
struct mq_attr msg_queue_attr;
int max_len;
char* buff;
uint_t prio;
if( argc < 3 )
{
printf( "Client: command line args error!!!\n" );
exit(2);
}
// Получаем доступ к очереди //
msg_queue_id_rd = mq_open( argv[1], O_RDONLY );
msg_queue_id_wr = mq_open( argv[1], O_WRONLY );
if( msg_queue_id_rd < 0 || msg_queue_id_wr < 0 )
{
printf( "Client: open queue error!!!\n" );
exit(3);
}
prio = atoi( argv[2] );
if( mq_getattr( msg_queue_id_rd, &msg_queue_attr ) < 0 )
{
printf( "Client: get queue attr error!!!\n" );
exit(4);
}
max_len = msg_queue_attr.mq_msgsize;
buff = (char*)malloc( max_len );
printf( "Client: connect is OK.\n" );
printf( "Message: " );
scanf( "%s", buff );
// Оправка сообщения серверу //
if( mq_send( msg_queue_id_wr, buff, strlen(buff), prio ) < 0 )
{
printf( "Client: send message error!!!\n" );
exit(5);
}
printf( "Client: send message is OK.\n" );
mq_close( msg_queue_id_wr );
// Прием ответа от сервера //
int n=0;
n = mq_receive( msg_queue_id_rd, buff, max_len, &prio );
if( n < 0 )
{
printf( "Client: message receive error!!!\n" );
exit(6);
}
mq_close( msg_queue_id_rd );
buff[n] = '\0';
printf( "Client: message received, length = %d\n", n );
printf( "Message: %s. ", buff );
printf( "Prio: %d\n", prio );
// Освобождаем выделенную память //
free( buff );
return EXIT_SUCCESS;
}
В программе-клиенте реализована отправка сообщения серверу и прием уведомления. При запуске в аргументах командной строки надо указать имя файла-очереди и приоритет сообщения, которое будет отправлено.
Результаты работы программы.
Терминал программы-сервера |
Терминал программы-клиента |
# ./server Server: start. Server: message received, length = 3 Message: hi! Prio: 4 Server: message received, length = 6 Message: qwerty Prio: 4 Server: message received, length = 3 Message: yo! Prio: 10 Server: terminate |
#./client server_queue 4 Client: connect is OK. Message: hi! Client: send message is OK. Client: message received, length = 2 Message: OK. Prio: 31 #./client server_queue 4 Client: connect is OK. Message: qwerty Client: send message is OK. Client: message received, length = 2 Message: OK. Prio: 31 #./client server_queue 10 Client: connect is OK. Message: yo! Client: send message is OK. Client: message received, length = 2 Message: OK. Prio: 31 |
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.