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