#include <semaphore.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include "../6_sem_server_ver_2/shared_mem.h"
void sigint_handler( int );
int main( int argc, char *argv[] )
{
struct SharedMem *p_shmem;
int fd_shm;
char msg[ MAX_MSG_SIZE ];
/* Открытие и отображение объекта разделяемой памяти */
fd_shm = shm_open( SHM_NAME, O_RDWR, PERM );
if( fd_shm < 0 )
{
printf( "Client: open shared memory error!!!\n");
exit(3);
}
p_shmem = mmap( NULL, sizeof(struct SharedMem), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0);
close( fd_shm );
printf( "Client: start.\n" );
signal( SIGINT, sigint_handler );
int i;
long offset;
char pid_str[32];
sprintf( pid_str, "PID=%d: ", getpid());
strcpy( msg, pid_str );
/* Цикл отправки сообщений серверу */
for ( i=0; ;++i )
{
write( 1, "Message: ", 9 );
scanf( "%s", &msg[ strlen(pid_str) ] );
sem_wait( &(p_shmem->nempty) );
sem_wait( &(p_shmem->mutex) );
offset = p_shmem->msg_offset[ p_shmem->nput ];
if( ++(p_shmem->nput) >= MAX_NUM_MSG )
{
p_shmem->nput = 0;
}
sem_post( &(p_shmem->mutex) );
strcpy( &(p_shmem->msg_data[offset] ), msg );
sem_post( &(p_shmem->nstored) );
}
return EXIT_SUCCESS;
}
void sigint_handler( int signo )
{
printf( "\nClient: terminate.\n");
exit(0);
}
Программа-клиент ожидает освобождения места в буфере, потом записывает туда сообщение и увеличивает счетчик занятых полей в буфере.
Завершение программы так же осуществляется по сигналу SIGINT.
Результаты работы приложения.
Консоль сервера |
Консоль клиента 1 |
Server: start. Message: PID=1396778: hi! Message: PID=1396777: yo! Message: PID=1396776: hello! Message: PID=1396778: 666 Message: PID=1396777: qwerty Message: PID=1396776: ololololol Server: terminate. Shared memory deleted. |
Client: start. PID=1396778: Message: hi! Message: 666 Message: Client: terminate. |
Консоль клиента 2 |
|
Client: start. PID=1396777: Message: yo! Message: qwerty Message: Client: terminate. |
|
Консоль клиента 3 |
|
Client: start. PID=1396776: Message: hello! Message: ololololol Message: Client: terminate. |
7. Межсетевой обмен сообщениями с применением IPCPosix.
На примере очереди сообщений.
В данном случае обмен сообщениями между двумя процессами на разных узлах сети возможен, если известен путь к файлу очереди сообщений.
Сервер создает очередь сообщений, а клиенту указывается путь к файлу очереди через /net/<имя узла>/.
Пример работы программы из пункта 1.5.
Листинг 7.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 );
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.