Jump to content
nunolevezinho

Servidor recebe comando "atrasado"

Recommended Posts

nunolevezinho

Boas, estou a fazer um programa que tem um "cliente" e "servidor" baseado em pipes.

Inicialmente apenas quero introduzir palavras e quero que o cliente comunique com o servidor e faça a tradução dessas palavras. O programa está a fazer a tradução, mas primeira palavra só é traduzida após inserir a segunda palavra. Ou seja existe sempre um "atraso" em relação ao que pretendo ver.

dict.h

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>

/* ficheiro correspondente ao FIFO do servidor */
#define SERVER_FIFO "server_fifo"

/* ficheiro correspondente ao FIFO do cliente n (n-> "%d") */
#define CLIENT_FIFO "resp_%d_fifo"

/* tamanho máximo de cada palavra */
#define TAM_MAX 50

/* estrutura da mensagem correspondente ao um pedido */
typedef struct {
pid_t pid_cliente;
   char palavra[TAM_MAX];
} pergunta_t;

/* estrutura da mensagem correspondente a uma resposta */
typedef struct {
   char palavra[TAM_MAX];
} resposta_t;

Servidor.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "dict.h"

#define RETURN_ERROR 0
#define RETURN_SUCCESS 1
#define MAX 256
#define NPALAVRAS 7

char * dicionario[NPALAVRAS][2] = 
{ 
{"memory", "memória" },
{"computer", "computador" },
{"close", "fechar" },
{"open", "abrir" },
{"read", "ler" },
{"write", "escrever" },
{"file", "ficheiro" } 
};

/*
O dicionário
é constituído
por uma matriz
bidimensional de
ponteiros para
caractere.
[i][0] = palavra
[i][1] = tradução
*/

int s_fifo_fd, c_fifo_fd, keep_alive_fd; /* descrição do ficheiro */

void sig_int(int i) {
   fprintf(stderr, "\nServidor a terminar (interrompido via teclado)\n\n");
   close(keep_alive_fd);
   close(s_fifo_fd);
   unlink(SERVER_FIFO);
   exit(EXIT_SUCCESS);
   /* termina o processo */
}

int main()
{
      pergunta_t perg;    /* mensagem do "tipo" pergunta */
   resposta_t resp;    /* mensagem do "tipo" resposta */
   int read_res,i;
   char c_fifo_fname[50];
   char * aux;
   signal(SIGINT, sig_int);

       //Cria Fifo para recepao de perguntas e abre-o
   if(mkfifo(SERVER_FIFO, 0777) == -1)
   {
       fprintf(stderr, "\nFIFO criado sem sucesso!");
   }
   s_fifo_fd = open(SERVER_FIFO, O_RDONLY); /* bloqueante */
   if (s_fifo_fd == -1) {
       fprintf(stderr, "\nErro ao abrir o FIFO");
       exit(EXIT_FAILURE);
   }

   keep_alive_fd = open(SERVER_FIFO, O_WRONLY);

   /* Ciclo Principal */

       while (1)
       {
           /* ---- a) OBTEM PERGUNTA ---- */
           read_res = read(s_fifo_fd, & perg, sizeof(perg));
           if (read_res < sizeof(perg))
               {
                   if (!strncasecmp("fim",(char *) & perg,3)) break;
                   else
                       {
                           fprintf(stderr, "\nPergunta incompleta!");
                           continue;
                       }
               }

           /* ---- b) PROCURA TRADUCAO ---- */
           aux = "DESCONHECIDO";
           for (i=0; i<NPALAVRAS; i++)
               if (!strcasecmp(perg.palavra,dicionario[i][0]))
                   {
                       aux = dicionario[i][1];
                       break;
                   }
           strcpy(resp.palavra,aux);

           /* ---- OBTEM FILENAME DO FIFO PARA A RESPOSTA ---- */

           sprintf(c_fifo_fname, CLIENT_FIFO, perg.pid_cliente);

           /* ---- c) ENVIA RESPOSTA ---- */

           c_fifo_fd = open(c_fifo_fname, O_WRONLY | O_NONBLOCK);
           if (c_fifo_fd != -1)
               {
                   write(c_fifo_fd, & resp, sizeof(resp));
                   close(c_fifo_fd); /* FECHA LOGO O FIFO ! */
               }
           else
               fprintf(stderr, "\nNinguem quis a resposta [%s]", resp.palavra);
       } /* ciclo principal */

   close(keep_alive_fd);
   close(s_fifo_fd);
   unlink(SERVER_FIFO);

   /* FIM do main aqui */

   return RETURN_SUCCESS;

}

Cliente.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "dict.h"

#define RETURN_ERROR 0
#define RETURN_SUCCESS 1
#define MAX 256

int main()
{

   int s_fifo_fd;     /* identificador do FIFO do servidor */
   int c_fifo_fd;   /* identificador do FIFO deste cliente */
   pergunta_t perg; /* mensagem do "tipo" pergunta */
   resposta_t resp; /* mensagem do "tipo" resposta */
   char buffer[80]; /* para a leitura da palavra a traduzir */
   char c_fifo_fname[25]; /* nome do FIFO deste cliente */
   long fflags;
   int read_res;

   //Abrir fifo do servidor
   s_fifo_fd = open(SERVER_FIFO, O_WRONLY); /* bloqueante */
   if (s_fifo_fd == -1) {
       fprintf(stderr, "\nO servidor não está a correr\n");
       exit(EXIT_FAILURE);
   }

   //Cria fifo para receber resposta do servidor
   perg.pid_cliente = getpid();
   sprintf(c_fifo_fname, CLIENT_FIFO, perg.pid_cliente);
   if (mkfifo(c_fifo_fname, 0777) == -1) {
       fprintf(stderr, "\nErro no FIFO para a resposta (1)");
       close(s_fifo_fd); exit(EXIT_FAILURE);
   }

   //Abre o fifo para receber a resposta do servidor
   c_fifo_fd = open(c_fifo_fname, O_RDONLY | O_NONBLOCK);
   if (c_fifo_fd == -1) {
       fprintf(stderr, "\nErro no FIFO para a resposta (2)\n");
       close(s_fifo_fd);
       unlink(c_fifo_fname);
       exit(EXIT_FAILURE);
   }

   fflags = fcntl(c_fifo_fd, F_GETFL);
   fflags ^= O_NONBLOCK; /* inverte a semântica de bloqueio */
   fcntl(c_fifo_fd, F_SETFL, fflags); /* bloqueante = on */

   perg.palavra[TAM_MAX-1] = '\0';

   /* Ciclo Principal */

   while (1) { /* caso escreva "fim" o programa termina */

       /* ---- a) OBTEM PERGUNTA ---- */
       printf("Palavra a traduzir -> ");
       scanf("%s",buffer);

       if (!strcasecmp("fim",buffer)) break; 

       strncpy(perg.palavra,buffer,TAM_MAX-1); //copia a palavra lida do "buffer" para a "perg.palavra"

       /* ---- b) ENVIA A PERGUNTA ---- */
       write(s_fifo_fd, & perg, sizeof(perg));

       /* ---- c) OBTEM A RESPOSTA ---- */
       read_res = read(c_fifo_fd, & resp, sizeof(resp));
       if (read_res == sizeof(resp))
           printf("Traducao -> %s\n", resp.palavra);
       else
           printf("Sem resposta ou resposta incompreensivel[%d]\n",read_res);
   }

   close(c_fifo_fd);
   close(s_fifo_fd);
   unlink(c_fifo_fname);    

   printf("Programa Terminou com Exito!");
   return RETURN_SUCCESS;

}

PS: Nos ficheiros de cabeçalho tenho de fazer os #includes ?

Edited by nunolevezinho

Share this post


Link to post
Share on other sites
HappyHippyHippo

indenta correctamente o ciclo principal do servidor


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
nunolevezinho

indenta correctamente o ciclo principal do servidor

Penso que já esteja bem agora Edited by nunolevezinho

Share this post


Link to post
Share on other sites
HappyHippyHippo

podes fazer copy-paste da consola cliente (tudo que aparece : o que escreveste e o que apareceu sem esquecer os '\n')


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
nunolevezinho

CWvlvpD.png

Escrevi:

./Cliente <ENTER>
computer <ENTER>
memory <ENTER>
write <ENTER>
file <ENTER>

Edited by nunolevezinho

Share this post


Link to post
Share on other sites
HappyHippyHippo

o que está a acontecer é que o cliente está a "tentar" ler a resposta antes do servidor a escrever no pipe.

é um problema de sincronismo

faz este teste :


// cliente.c

/* ---- b) ENVIA A PERGUNTA ---- */
write(s_fifo_fd, & perg, sizeof(perg));

sleep(1); // <-- espera 1 segundo

/* ---- c) OBTEM A RESPOSTA ---- */
read_res = read(c_fifo_fd, & resp, sizeof(resp));
[/Code]


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.