
- •Лабораторная работа №3
- •Цель работы
- •Выполнение
- •Сигналы
- •Сообщения
- •Передача сообщений между родственными процессами
- •Передача сообщений между потоками одного процесса
- •Передача сообщений между независимыми процессами (неименованные каналы)
- •Передача сообщений между независимыми процессами (именованные каналы)
Передача сообщений между независимыми процессами (именованные каналы)
Листинг 2.5. Сервер. msg_server_name_attach.c.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <sys/dispatch.h>
#define ATTACH_POINT "qnx_msg_server"
#define BUF_LEN 256
typedef union {
struct
_pulse pulse_msg;
char msg_buff[ BUF_LEN ];
} Msg_T;
void Sigint_Handler( int );
void ClientMsgProc();
name_attach_t* msg_chanel;
dispatch_t* dpp;
Msg_T msg;
int rcvid;
struct
_msg_info msg_info;
int main( int argc, char *argv[] )
{
// Проверка командных опций программы //
if( argc < 2 ) {
printf( "Server: 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( "Server: cmd args error!\n" );
exit(2);
}
// Отключаем буферизацию вывода //
setbuf( stdout, NULL );
// Регистрация канала //
dpp = dispatch_create();
msg_chanel = name_attach( dpp, ATTACH_POINT, flag );
if (msg_chanel == NULL){
printf( "Server: name attach error!\n" );
exit(3);
}
printf( "Server: started.\n");
// Завершение сервера по SIGINT //
signal( SIGINT, Sigint_Handler );
// Цикл ожидания и приема сообщений //
while (1)
{
rcvid = MsgReceive( msg_chanel->chid, &msg, sizeof(msg), &msg_info );
switch (rcvid)
{
// Ошибка //
case -1:
printf( "Server: msg receive error!\n" );
exit(4);
break;
// Принят пульс //
case 0:
printf( "Server: Receive pulse!\n" );
break;
// Принято сообщение //
default:
if (msg.pulse_msg.type == _IO_CONNECT ) {
MsgReply( rcvid, EOK, NULL, 0 );
} else {
ClientMsgProc();
}
break;
}
}
// Удаление канала //
name_detach( msg_chanel, 0 );
return EXIT_SUCCESS;
}
void Sigint_Handler( int signo ) {
// Удаление канала //
name_detach( msg_chanel, 0 );
printf( "\nSetver: terminate. Chanel delete.\n" );
exit(EXIT_SUCCESS);
}
void ClientMsgProc( )
{
printf( "PID=%d, ND=%d. ", msg_info.pid, msg_info.nd );
printf( "Recieved Message: %s\n", msg.msg_buff );
strcpy( msg.msg_buff, "OK!" );
MsgReply( rcvid, EOK, &msg, sizeof(msg) );
}
Листинг 2.6. Клиент. msg_client_name_open.c.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/dispatch.h>
#define ATTACH_POINT "qnx_msg_server"
#define BUF_LEN 256
void sigint_handler( int );
int coid;
int main( int argc, char *argv[] )
{
char send_buff[ BUF_LEN ];
char reply_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(2);
}
// Отключаем буферизацию вывода //
setbuf( stdout, NULL );
// Открытие канала //
coid = name_open( ATTACH_POINT, flag );
if (coid == -1) {
printf( "Client: name open error!\n" );
exit(3);
}
printf( "Client: started. PID=%d.\n", getpid() );
signal( SIGINT, sigint_handler );
while(1)
{
printf( "Message: ");
scanf( "%s", send_buff );
if ( MsgSend( coid, send_buff, sizeof(send_buff), reply_buff, sizeof(reply_buff) ) == -1 ) {
printf( "Client: send msg error!\n" );
break;
}
printf( "Server reply message: %s \n", reply_buff );
fflush( stdout );
}
// Закрытие локального канала //
name_close( coid );
return EXIT_SUCCESS;
}
void sigint_handler( int signo ) {
// Закрытие канала //
name_close( coid);
printf( "\nClient: terminate.\n" );
exit(0);
}
Результаты:
Локальный обмен
Сервер |
Клиент №1 |
$ ./msg_server_name_attach.out -l Server: started. PID=1212459, ND=0. Recieved Message: yo PID=1224750, ND=0. Recieved Message: hello PID=1224750, ND=0. Recieved Message: bye PID=1212459, ND=0. Recieved Message: hey Receieved Message: Setver: terminate. Chanel delete.
|
$ ./msg_client_name_open.out -l Client: started. PID=1212459. Message: yo Server reply message: OK! Message: hey Server reply message: OK! Message: Client: terminate.
|
-
Клиент №2
$ ./msg_client_name_open.out -l
Client: started. PID=1224750.
Message: hello
Server reply message: OK!
Message: bye
Server reply message: OK!
Message:
Client: terminate.
Сетевой обмен
Предварительно надо запустить gns на используемых узлах сети. /usr/sbin/gns -s — на компьютере сервера и /usr/sbin/gns -с на компьютере клиента.
Сервер |
Клиент №1 |
# ./msg_server_name_attach.out -g Server: started. PID=913460, ND=4. Recieved Message: Hello_bro! PID=913460, ND=4. Recieved Message: yo! Setver: terminate. Chanel delete.
|
# ./msg_client_name_open.out -g Client: started. PID=913460. Message: Hello_bro! Server reply message: OK! Message: yo! Server reply message: OK!
|
Пульсы