Сигналы. Сетевая доставка сигналов. Системный вызов. Отправка сигнала процессу на удаленном узле. Программа приема сигнала, страница 9

5. Передача сообщений с использованием файловой модели.

Каналы  и  соединения  после  своего создания  получают идентифицирующие номера – малые целые числа, которые берутся из  пространства файловых дескрипторов.

Поэтому для обмена сообщениями можно использовать функции стандартной библиотеки языка Си.

Пример. Используем программу сервера из предыдущего пункта. Программа клиент, открывает канал и использует его как файловый дескриптор в функциях read и write.

Листинг 5.1. Программа-клиента. (Файл 2_5_file_client.c).

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <string.h>

#include <sys/dispatch.h>

#define ATTACH_POINT      "qnx_msg_server"

#define BUF_LEN                  256

int    connect_id;

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

{

char   buff[ BUF_LEN ];

if( argc < 2 ) {

printf( "Client: cmd args error!\n" );

exit(1);

}

unsigned int flag;

if (strcmp(argv[1],"-l" ) == 0)               flag = 0;

else if (strcmp(argv[1],"-g") == 0 )   flag = NAME_FLAG_ATTACH_GLOBAL;

else {

printf( "Client: cmd args error!\n" );

exit(1);

}

// Отключаем буферизацию вывода //

setbuf( stdout, NULL );

// Открытие канала //

connect_id = name_open( ATTACH_POINT, flag );

if( connect_id == -1 ) {

printf( "Client: name open error!\n" );

exit(2);

}

printf( "Client: started. PID=%d.\n", getpid() );

strcpy( buff, "Hello!" );

printf( "Client: Write msg - %s\n", buff );

write( connect_id, buff, strlen(buff) );

sleep(1);

read( connect_id, buff, BUF_LEN );

printf( "Client: Read msg - %s!\n", buff );

// Закрытие локального канала //

name_close( connect_id );

return EXIT_SUCCESS;

}

Результаты работы приложения. Результаты работы программы. Программы запускались прямо из IDE(Run As C/C++ QNX Application). Результаты работы выводятся на консоль в IDE.

Аргументы командной строки для клиента задавались в Run Configuration->Arguments->«-l» или «-g». Первый аргумент — имя файла очереди сообщений, второй приоритет передаваемого сообщений

Результаты работы программы. Локальный вариант. Опция -l.

Клиент:

Client: started. PID=1789991.

Client: Write msg - Hello!

Client: Read msg - OK!!

Сервер:

Server: started.

PID=1789991, ND=0. Recieved Message:

PID=1789991, ND=0. Recieved Message:

Результаты работы программы. Сетевой вариант. Опция -g.

Клиент:

Client: started. PID=782376.

Client: Write msg - Hello!

Client: Read msg - OK!!

Сервер:

Server: started.

PID=782376, ND=5. Recieved Message:

PID=782376, ND=5. Recieved Message:

PID=782376, ND=5. Recieved Message:

Сервер не совсем правильно обрабатывает запросы, так как он был сделан не под эту задачу, но видно, что можно использовать для обмена сообщениями по каналу любые функции, которые используют файловые дескрипторы.

Профилирование приложения. Локальный вариант.

Timeline-диаграммы и Trace Log клиента и сервера.




6. Анализ реализации очереди сообщений POSIX.

Исходные тексты программ, клиента и сервера.

Листинг 6.1. Программа сервера. 2_6_posix_msg_server.с.

/*

* Сообщения 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;