Санкт-Петербургский государственный технический университет Факультет Технической Кибернетики
Кафедра Компьютерных Систем и Программных Технологий
ЛАБОРАТОРНАЯ РАБОТА №1
Дисциплина: Системное программное обеспечение
Тема: Сообщения и пульсы в QNX Neutrino
Выполнил студент гр. 4081/1
Руководитель, к.т.н., доцент
"___ "_________ 2011 г.
Санкт-Петербург 2011
Цель работы:
1) Разработать программы сервера и клиента, которые обмениваются сообщениями (пульсами). Рассмотреть реализацию сервера и клиента как родственные процессы, и как отдельные процессы.
2) Создать приложение сервера, которое не обрабатывает сообщения от клиентов, а перенаправляет их ранее созданным агентам.
3) Создать приложение, посылающее пульс при нажатии на определённую последовательность клавиш, с использованием ISR.
1. Передача сообщений между родственными процессами
1.1. Pipe
Для передачи сообщений между родственными процессами можно использовать неименной канал – pipe. Для того, чтобы читать и писать в канал используются функции read() и write():
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int fildes[2];
char buf[20];
ssize_t nbytes;
int status;
int main(){
status = pipe(fildes);
if (status == -1 ) {
printf("\n Error create pipe \n");
}
switch ( fork() ){
case -1: // ошибка при создании процесса потомка
break;
case 0: // процесс потомок
close(fildes[1]);
nbytes = read(fildes[0], buf, 20);
close(fildes[0]);
printf("\n Get string = %s \n", buf);
exit(EXIT_SUCCESS);
default: // процесс родитель
close(fildes[0]);
write(fildes[1], "Hello world\n", 20);
close(fildes[1]);
exit(EXIT_SUCCESS);
}
return 0;
}
Результат выполнения программы:
./msg
Get string = Hello world
1.2. Передача сообщений с помощью MsgSend
Далее рассмотрим обмен сообщениями с помощью функций MsgSend() MsgReceive() MsgReply().
Для взаимодействия процессов, сервер создаёт канал с помощью функции channelCreate:
#include <sys/neutrino.h>
int ChannelCreate( unsigned flags );
После создания канала, создаём дочерний процесс и передаём ему номер созданного канала. После чего сервер вызывает функцию MsgReceive
#include <sys/neutrino.h>
int MsgReceive( int chid,
void * msg,
int bytes,
struct _msg_info * info );
, и переходит в состояние Receive-block, пока ему не отправят сообщение.
Клиент вызывает функции ConnectAttach:
#include <sys/neutrino.h>
int ConnectAttach( uint32_t nd,
pid_t pid,
int chid,
unsigned index,
int flags );
Открывая при этом канал, через который он будет отсылать сообщение серверу.
Посылка сообщения осуществляется с помощью команды MsgSend():
#include <sys/neutrino.h>
int MsgSend( int coid,
const void* smsg,
int sbytes,
void* rmsg,
int rbytes );
, после которой клиент уходит в состояние Send-block, а сервер получает сообщение, обрабатывает его и отвечает клиенту с помощью функции MsgReply():
#include <sys/neutrino.h>
int MsgReply( int rcvid,
int status,
const void* msg,
int size );
Код клиента и сервера приведён ниже.
Листинг 1. Server.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 );
if( fork() == 0 ){
// child process
itoa( chid, chid_s, 10 );
if( execl( "client", "child", chid_s, NULL ) == -1 )
printf("Execute child process is fail !\n ");
exit( EXIT_SUCCESS );
}
// parent process
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;
}
Листинг 2. Client.c
#include <sys/neutrino.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char** argv ){
int coid, nbyte=255, chid;
char buf[255], rbuf[255];
struct _msg_info* info;
chid = atoi( argv[1] );
coid = ConnectAttach( 0, getppid(), chid, 0, 0 );
if( coid == -1 ){
printf("Error connect ID???\n");
exit( EXIT_FAILURE );
}
strcpy( buf, "sending msg!!!" );
MsgSend( coid, buf, 255, rbuf, 255 );
printf("CLIENT!!!\n Client get msg = %s \n", rbuf );
return 0;
}
Пример выполнения программы:
# ./msg_serv
FROM SERV!!!
Serv get msg = sending msg!!!
FROM Client!!!
Client get msg = Server get msg!
2. Передача сообщений между не родственными процессами.
2.1. Связь клиента с сервером с помощью name_open, зная имя канала
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.