2.2. Использование MsgDeliverEvent
Рассмотрим использование функции MsgDeliverEvent().
Заголовочный файл header.h:
struct my_msg
{
short type;
struct sigevent event;
};
#define MY_PULSE_CODE _PULSE_CODE_MINAVAIL+5
#define MSG_GIVE_PULSE _IO_MAX+4
#define MY_SERV "my_server_name"
Программа server4.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/iomsg.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include "header.h"
int main() {
int rcvid;
struct my_msg msg;
name_attach_t *attach;
// Регистрация префикса и создание канала
if ( (attach = name_attach( NULL, MY_SERV, 0 )) == NULL) {
printf("Server: failed to attach name, errno %d\n", errno );
return EXIT_FAILURE;
}
// Ожидание сообщения от клиента
rcvid = MsgReceive( attach->chid, &msg, sizeof( msg ), NULL );
if (rcvid) {
// Отвечаем клиенту сразу
MsgReply(rcvid, 0, NULL, 0);
if ( msg.type == MSG_GIVE_PULSE ) {
// Делаем временную задержку, имитирующую обработку данных сервером
printf("Server: I'm work\n");
sleep(2);
// Доставляем событие клиенту
MsgDeliverEvent( rcvid, &msg.event );
printf("Server: delivered event\n");
} else {
printf("Server: unexpected message\n");
}
}
name_detach(attach, 0);
return EXIT_SUCCESS;
}
Программа client4.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/iomsg.h>
#include "header.h"
int main() {
int chid, coid, srv_coid, rcvid;
struct my_msg msg;
struct _pulse pulse;
// Создание канала для получения пульса от сервера
chid = ChannelCreate( 0 );
// Создаём соединение
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );
// Заполнение event-структуры для пульса
SIGEV_PULSE_INIT( &msg.event, coid, SIGEV_PULSE_PRIO_INHERIT, MY_PULSE_CODE, 0 );
msg.type = MSG_GIVE_PULSE;
// Присоединение к каналу
if ((srv_coid = name_open( MY_SERV, 0 )) == -1) {
printf("Failed to find server");
return EXIT_FAILURE;
}
// Отправляем сообщение
MsgSend( srv_coid, &msg, sizeof(msg), NULL, 0 );
printf("Client: I'm work\n");
// Ожидаем пульс от сервера
rcvid = MsgReceivePulse( chid, &pulse, sizeof( pulse ), NULL );
printf("Client: got pulse with code %d, waiting for %d\n", pulse.code,
MY_PULSE_CODE );
// Закрываем соединение
name_close(coid);
return EXIT_SUCCESS;
}
Результат выполнения программ представлен на рис. 1.11.
Рис. 1.11. Результат
Как видно из результатов выполнения программ, клиент после отправки сообщения серверу может продолжать работу, как и собственно сервер. После обработки сообщения сервер уведомляет клиента о выполнении работы, посылая импульс с помощью команды MsgDeliverEvent().
2.3. Отправка импульса по завершению обработки прерывания
Рассмотрим программу, отправляющую импульс при нажатии любой клавиши клавиатуры.
Программа server5.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/dispatch.h>
#include <sys/neutrino.h>
#define MY_SERV "my_server_name"
int main() {
struct _pulse pulse;
name_attach_t *attach;
// Регистрация префикса и создание канала
if ( (attach = name_attach( NULL, MY_SERV, 0 )) == NULL) {
printf("Server: failed to attach name\n" );
return EXIT_FAILURE;
}
while (1) {
// Ожидание пульса от клиента
MsgReceivePulse(attach->chid, &pulse, sizeof(pulse), NULL);
if (pulse.code != _PULSE_CODE_DISCONNECT) {
printf("Server: pulse from client: pulse.code = %d, pulse.value = %d\n", pulse.code, pulse.value);
}
else {
printf("Server: disconnect pulse from client\n");
}
}
name_detach(attach, 0);
return EXIT_SUCCESS;
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.