Средства межпроцессного взаимодействия (IPC) в ОС LINUX. Семафоры и разделяемая память. Ненадежные сигналы, страница 4

n;

/* Чтение FIFO */

n = read(read_fd, input_file_name, BUF_LEN);

input_file_name[ n ] = '\0';

printf( "Client: read FIFO is OK!!!\n" );

printf( "Client: input file name %s.\n", input_file_name );

/* Открываем указанный файл */

input_file_fd = open( input_file_name, O_RDONLY );

if( input_file_fd < 0 )

{

printf( "Client: error, can not open file %s", input_file_name );

exit(4);

}

/* Читаем из файла в буфер и передаем сереверу */

while( ( n = read(input_file_fd, buf, BUF_LEN) ) > 0 ) {

if ( write(write_fd, buf, n) != n )

{

printf( "Client: error output!!!\n" );

exit(5);

}

}

close( input_file_fd );

}

Результаты работы программы.

# cat buf_file.txt

123234tsdgadsgzvzsdvzvzc

# ./server

Server: create FIFO is OK!!!

Server: open FIFO is OK!!!

Server: write is OK!!!

Server: read data...

123234tsdgadsgzvzsdvzvzc

# ./client

Client: open FIFO is OK!!!

Client: read FIFO is OK!!!

Client: input file name buf_file.txt.

В файл записываются какие-то данные. Сервер передает имя этого файла клиенту, клиент читает содержимое файла и передает данные серверу.

5. Очереди сообщений.

Следующие программы демонстрируют работу с очередью сообщений.

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

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

Листинг 5.1.1. Программа-сервер. Файл msg_server.c.

/*

* Сообщения Posix

* Программа сервера

*/

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <mqueue.h>

#include "mysignal.h"

#define                   PERM   0666

#define             QUEUE_NAME  "server_queue"

mqd_t               msg_queue_id;

struct mq_attr      msg_queue_attr;

struct sigevent notification;

int main( int argc, char *argv[] )

{

printf( "Server: start.\n" );

/* Создаем очередь сообщений или открываем существующую */

msg_queue_attr.mq_maxmsg = 1024;

msg_queue_attr.mq_msgsize = BUF_LEN;

msg_queue_id = mq_open( QUEUE_NAME, O_RDWR | O_CREAT, PERM, &msg_queue_attr );

if( msg_queue_id < 0 )

{

printf( "Server: create/open queue error!!!\n" );

exit(1);

}

/* Устновка диспозиции для SIGINT */

signal( SIGINT, sigint_handler );

/* Устанавливаем режим уведомления о сообщении сигналом SIGUSR1 */

signal( SIGUSR1, sigusr1_handler );

SIGEV_SIGNAL_INIT( &notification, SIGUSR1 );

if( mq_notify( msg_queue_id, &notification ) < 0 )

{

printf( "Server: set notify mode queue error!!!\n" );

exit(2);

}

/* Ожидаем сообщений от клиента  */

while(1)

{

// Ожидаем сигнала //

pause( );

}

return EXIT_SUCCESS;

}

Листинг 5.1.2. Пользовательские обработчики сигналов. Файл mysignal.h.

/*

* Обработкчики сигналов

*/

#ifndef MYSIGNAL_H_

#define MYSIGNAL_H_

#define BUF_LEN     80

#define QUEUE_NAME  "server_queue"

/* Обработчки сигнала SIGINT */

void sigint_handler( int );

/* Обработчки сигнала SIGUSR1 */

void sigusr1_handler( int );

#endif

Листинг 5.1.3. Пользовательские обработчики сигналов. Файл mysignal.c.

#include <stdlib.h>

#include <signal.h>

#include <stdio.h>

#include <mqueue.h>

#include "mysignal.h"

char   buff[ BUF_LEN ];

uint_t prio;

/* Обработчик сигнала SIGINT */

void sigint_handler( int signo )

{

extern mqd_t msg_queue_id;

/* Закрываем очередь сообщений */

if( mq_close( msg_queue_id ) < 0 )

{

printf( "Server: close queue error!!!\n" );

exit(3);

}

/* Удаление очереди сообщений */

if( mq_unlink( QUEUE_NAME ) < 0 )

{

printf( "Server: delete queue error!!!\n" );

exit(4);

}

printf( "Server: terminate\n" );

exit(0);

}

/* Обработчки сигнала SIGUSR1 */

void sigusr1_handler( int signo )

{

extern mqd_t msg_queue_id;