Сигналы. Сетевая доставка сигналов. Системный вызов. Отправка сигнала процессу на удаленном узле. Программа приема сигнала, страница 12

#define AGENT_START       30

#define AGENT_REPLY       31

#define      CLIENT_REQUEST      32

#endif

Листинг 7.2. Программа сервера. Файл reply_driven_server.c.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <errno.h>

#include <fcntl.h>

#include <pthread.h>

#include <sys/dispatch.h>

#include "defs.h"

void MsgHandler( int rcv_id );

int SearchFreeAgent( );

void ReleaseAgent( int rcv_id );

name_attach_t*      msg_chanel;

ClientMsg_T client_msg;

AgentMsg_T   agent_msg;

Msg_T        msg;

AgentInfo*   agent_info;

int agent_num;

ClientQueue client_queue;

int main( int argc, char *argv[] )

{

unsigned int flag;

char cmd_args[16];

char file_name[128];

FILE* agent_inf_file;

// Проверка командных опций программы //

if( argc < 3 ) {

printf( "Server: cmd args error!" );

exit(1);

}

if( strcmp(argv[1],"-l" ) == 0 ) {

flag = 0;

strcpy( cmd_args, argv[1] );

}

else if( strcmp(argv[1],"-g" ) == 0 ) {

flag = NAME_FLAG_ATTACH_GLOBAL;

strcpy( cmd_args, argv[1] );

}

else {

printf( "Server: cmd args error!" );

exit(1);

}

strcpy( file_name, argv[2] );

agent_inf_file  = fopen( file_name, "r" );

if( agent_inf_file == NULL ) {

printf( "Server: open config file error=%d!", errno );

exit(2);

}

fscanf( agent_inf_file, "%d", &agent_num );

// Регистрация канала //

msg_chanel = name_attach( NULL, ATTACH_POINT, flag );

if( msg_chanel == NULL )

{

printf( "Server: name attach error!\n" );

exit(3);

}

printf( "Server: started.\n" );

// Порождение агентов, заданное число штук //

agent_info = (AgentInfo*)calloc( agent_num, sizeof(AgentInfo) );

int i=0;

for( i=0; i<agent_num; ++i ) {

fscanf( agent_inf_file, "%s", agent_info[i].file_name );

agent_info[i].busy = 1;

agent_info[i].pid = spawnl( P_NOWAIT, agent_info[i].file_name,

agent_info[i].file_name, cmd_args, NULL );

if( agent_info[i].pid < 0 ) {

printf( "Server: create agent error!\n" );

exit(4);

}

}

// Ожидание и прием сообщений //

int rcv_id;

while(1)

{

rcv_id = MsgReceive( msg_chanel->chid, &msg, sizeof(msg), NULL );

switch( rcv_id )

{

// Ошибка //

case -1:

printf( "Server: msg receive error!\n" );

exit(5);

break;

// Принят пульс //

case 0:

break;

// Принято сообщение, от клиента или от агента проверяем//

default:

MsgHandler( rcv_id );

break;

}

}

return EXIT_SUCCESS;

}

/* Процедура обработки сообщений */

void MsgHandler( int rcv_id )

{

static int init_ind = 0;

int agent_recv_id;

int client_recv_id;

switch( msg.AgentMsg.type )

{

// Регистрация агентов //

case AGENT_START:

agent_info[ init_ind ].recv_id = rcv_id;

agent_info[ init_ind ].busy = 0;

++init_ind;

break;

// Результат работы агента //

case AGENT_REPLY:

// Ответ клиенту //

client_recv_id = msg.AgentMsg.client_rcvid;

MsgReply( client_recv_id, NULL, msg.ClientMsg.msg_buff, sizeof(msg.ClientMsg.msg_buff) );

// Проверяем очередь //

if( client_queue.puts != 0 ) {

}

else {

// освобождаем агента //

ReleaseAgent( rcv_id );

}

break;

// Сообщение от клиента //

case CLIENT_REQUEST:

// Поиск свободного агента //

agent_recv_id = SearchFreeAgent( );

if( agent_recv_id != 0 ) {                    // свободный есть

msg.AgentMsg.client_rcvid = rcv_id;

MsgReply( agent_recv_id, NULL, &(msg.AgentMsg), sizeof(msg.AgentMsg) );

}

else {                                                     // в очередь

if( client_queue.index == QUEUE_LEN-1 )

client_queue.index = 0;

else

++client_queue.index;

client_queue.ClientBuf[client_queue.index].recv_id = rcv_id;

strcpy( client_queue.ClientBuf[client_queue.index].msg_buf,