Сообщения и пульсы в QNX Neutrino. Передача сообщений между родственными процессами. Передача сообщений с помощью MsgSend, страница 2

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

include <sys/iofunc.h>

#include <sys/dispatch.h>

name_attach_t * name_attach( dispatch_t * dpp,

const char * path,

unsigned flags );

создаёт канал в каталоге /dev/name/[local|global]/.

Структура struct _name_attach  имеет следующие параметры:

typedef struct _name_attach {

dispatch_t* dpp;

int         chid;

int         mntid;

int         zero[2];

} name_attach_t;

Где chid – номер созданного канала, по которому сервер будет ожидать сообщения от клиента.

Если функция MsgReceive возвращает ноль, то это значит что пришёл pulse. В данном примере мы не будем рассматривать сообщения от pulse, а только выведем на экран сообщение о том, что пришёл pulse.

Клиент открывает канал с помощью функции name_open():

#include <sys/iofunc.h>

#include <sys/dispatch.h>

int name_open( const char * name,

int flags );

которая возвращает при удачном исходе side-channel connection ID. Это значением мы используем для отправки сообщения с помощью MsgSend().

Код клиента и сервера приведён ниже.

Листинг 3. Server.c

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <string.h>

#include <sys/dispatch.h>

#include <string.h>

#define ATTACH_POINT "channel_lab1"

int main(){

name_attach_t           *attach;

struct _msg_info  *info;

int                                      nbyte=255, rcvid;

char                               buf[255];

if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL) {

printf("name Attach fail ???\n");

return EXIT_FAILURE;

}

while(1){

rcvid = MsgReceive( attach->chid, &buf[0], sizeof(buf), NULL );

if( rcvid > 0 ){

//Message

printf("SERVER tell with you!!!\n  Serv get msg = %s\n", buf );

strcpy( buf, "Hello Client!!" );

MsgReply( rcvid, 0, &buf[0], sizeof( buf ) );

}

}//end while(1)

name_detach(attach, 0);

return 0;

}

Листинг 4. Client.c

#include <sys/neutrino.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/iofunc.h>

#include <sys/dispatch.h>

#define PATH "channel_lab1"

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, "I am the client" );

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

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

name_close( fd );

return 0;  

}

Пример выполнения программы:

# ./serv

# ./client

SERVER tell with you!!!

Serv get msg = I am the client

CLIENT!!!

Client get = Hello Client!!

2.2. Регистрация сервера по pid

Тоже что и в родственных процессах, только pid вводим вручную, а не передаём из клиента.

Serv.c

#include <sys/neutrino.h>

#include <stdio.h>

#include <stdlib.h>

int main(){

int               rcvid, nbyte=255;

char        buf[255], chid_s[10];

pid_t       chid ;

struct _msg_info* info;

chid = ChannelCreate( 0 );

printf("SERV create channel = %d ; PID server = %d\n", chid, getpid() );

rcvid = MsgReceive( chid, buf, nbyte, info );

if( rcvid > 0 ){

// Message

printf( "SERVER tell with you!!!\n  Server get msg = %s\n", buf );

if( MsgReply( rcvid, 0, "Server get msg!", nbyte ) == -1 )

printf("SERVER???\n  Don't Reply message to client\n");

}

return 0;

}

Client.c

#include <sys/neutrino.h>

#include <stdio.h>

#include <stdlib.h>

int main( int argc, char** argv ){

int               coid, nbyte=255, chid, ppid;

char        buf[255], rbuf[255];

struct _msg_info* info;

chid = atoi( argv[1] );

ppid = atoi( argv[2] );

coid = ConnectAttach( 0, ppid, chid, 0, 0 );

if( coid == -1 ){

printf("Error connect ID???\n");

exit( EXIT_FAILURE );

}