IPC микроядра на примере QNX Neutrino. Передача сообщений (функции send, receive, reply), страница 3

1.4. между независимыми процессами (с передачей имени)

Данный вариант программы использует функцию регистрации имени attach = name_attach(NULL, "Mess2",0);. Для получения идентификатора соединения клиент использует функцию name_open.

client:

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <sys/dispatch.h>

int main (void)

{

char send_buf [25];

char  msg_reply [25];

int fd;

fd = name_open("Mess2",0);   

strcpy(send_buf, "ask");

MsgSend(fd, &send_buf, sizeof(send_buf), &msg_reply, sizeof(msg_reply));

printf("CLIENT get: %s\n",msg_reply);   

name_close(fd);  

printf("\nEnd of client\n" );

return EXIT_SUCCESS;   

}

Server

#include <sys/iofunc.h>

#include <sys/dispatch.h>

#include <stdlib.h>

#include <stdio.h>

#include <malloc.h>

int main (void)

{

name_attach_t *attach;

int i, j ,k;

float M;

char receive_buf[25], reply_buf[25];

int   rcvid, chid;

strcpy(reply_buf, "Answer");

attach = name_attach(NULL, "Mess2",0);

while(1){

rcvid=MsgReceive(attach->chid, &receive_buf, sizeof(receive_buf), NULL);

printf("SERVER get: \"%s\"\n", receive_buf);  

MsgReply(rcvid, 0, &reply_buf, sizeof(reply_buf));

break;

}

ChannelDestroy(chid);

printf("\nEnd of server\n" );

return EXIT_SUCCESS;

}

Результаты:

$

$ ./server&

[1] 1568813

$ ./client

SERVER get: "ask"

End of server

CLIENT get: Answer

End of client

[1] + Done                 ./server

$

Для реализации локального варианта в качестве аргумента name_attach стоит 0.

Для того чтобы зарегистрировать глобальное имя, нужно указать NAME_FLAG_ATTACH_GLOBAL.

При отправке сообщения по сети Qnet между двумя компьютерами, на которых установлена ОС QNX необходимо:

1)  Запустить администратор GNS (Global Name Service) на одной машине в серверном режиме: /usr/sbin/gns –s, а на другой в клиентском: /usr/sbin/gns –с.

2)  Запустить программы в соответствии с режимами.

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

#

# ./server

SERVER get: ""

End of server

#

# ./client

CLIENT get: g%$&

End of client

Несовпадение отправляемых сообщений объясняется тем, что GNS автоматически отправляет некоторые настроечные сообщения, и именно их принимает сервер, что разблокирует его, сообщения от клиента он не дожидается.


2. Обмен пульсами

В отличии от сообщений, пульсы не требуют ответа. Т.е. клиент пославший пульс не перейдёт в состояние Send-block, а продолжит выполняться.

Сервер может принимать пульсы как с помощью функции MsgReceivePulse(), так и с помощью MsgReceive(). При использовании функции MsgReceive оповещением о том, что пришёл пульс будет равенство нулю выходного значения.

Использование функции MsgReceive для приёма пульсов показано на примере в программах приведенных ниже.

       2.1 передача функциями сообщений

               2.1.1 между независимыми процессами

client:

#include <sys/neutrino.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/iofunc.h>

#include <sys/dispatch.h>

#define PATH "channel_pulse_"

int main(){

int fd;

char  sbuf[255], rbuf[255];

fd = name_open( PATH, 0 );

if( fd == -1 ){

printf("Client name_open error\n" );

exit( EXIT_FAILURE );

}

strcpy( sbuf, "Client pulse" );

MsgSend( fd, &sbuf[0], sizeof(sbuf), &rbuf[0], sizeof(rbuf) );

printf("CLIENT:\n  Client get = %s \n", rbuf );

MsgSendPulse( fd, 0, 10, 5 );

name_close( fd );

return 0;  

}

Server

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <string.h>

#include <sys/dispatch.h>

#include <string.h>

#define ATTACH_POINT "channel_pulse"