Для передачи сообщений между не родственными процессами, т.е. если сервер создаст канал, то клиент не сможет узнать номер этого канала и подключиться к нему. По этому мы регистрируем канал по заранее заданному имени. Сервер с помощью функции 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 );
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.