2011-12-23 23 views
6

Sto provando a scrivere semplici programmi client e server C, comunicando tra loro in terminali separati.Connessione client-server FIFO corretta

Il server deve creare un pubblico fifo e attendere il client. Nel frattempo il cliente sta creando il proprio fifo attraverso il quale verrà la risposta del server. L'attività del client invia al server un nome creato dalla coda e ottiene in risposta il risultato del comando ls.

Ho cercato una risposta, ad esempio: fifo-server-program, example-of-using-named-pipes-in-linux-bash, how-to-send-a-simple-string-between-two-programs-using-pipes. Ho iniziato con il codice dal terzo link e lo ho modificato lentamente.

Quello che ho ora, è un client che riceve input dall'utente, lo invia al server e lo riceve indietro. Ma funziona solo una volta. Non ho idea del perché. Il corpo della funzione principale è sotto. Sarò grato per qualsiasi aiuto.

MODIFICA: Ho funzionato! : D I codici sono sotto, forse aiuterà qualcuno.

Il codice server.c:

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char tab[BUFSIZ]; 
    int fd, n; 

    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    pipe(fds); 
    mkfifo(myfifo,0666); 

    while(1) 
    { 
     fds[0]=open(myfifo2,O_RDONLY); 
     fds[1]=open(myfifo,O_WRONLY); 

     read(fds[0],tab,BUFSIZ); 

     if (strcmp("klient",tab)==0) { 
      printf("Od klienta: %s\n",tab); 
      fd=open(tab,O_WRONLY); 

      if(fork()==0) 
      { 
       dup2(fds[1],1); 
       close(fds[1]); 
       execlp("ls","ls","-l",NULL); 
       close(fds[0]); 
       close(fds[1]); 
      } 
      else 
      { 
       dup2(fds[0],0); 
       n = read(fds[0],tab,BUFSIZ); 
       write(fd,tab,n); 
       close(fds[0]); 
       close(fds[1]); 
      } 
     } 
     memset(tab, 0, sizeof(tab)); 
     close(fd); 
     close(fds[0]); 
     close(fds[1]); 
    } 

    unlink(myfifo); 
    return 0; 
} 

Il codice client.c:

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    mkfifo(myfifo2,0666); 
    fds[0]=open(myfifo,O_RDONLY); 
    fds[1]=open(myfifo2,O_WRONLY); 

    char tab[BUFSIZ]; 
    memset(tab, 0, sizeof(tab)); 

    write(fds[1],"klient",6); 
    perror("Write:"); //Very crude error check 
    read(fds[0],tab,sizeof(tab)); 
    perror("Read:"); // Very crude error check 

    printf("Odebrano od serwera: %s\n",tab); 

    close(fds[0]); 
    close(fds[1]); 
    unlink(myfifo2); 
    return 0; 
} 
+1

Non è chiaro da questo codice. Hai ottenuto l'output ls o stai solo inviando piccoli msg? La solita trappola in questo scenario è che ti trovi in ​​una condizione di stallo, il server è in attesa di input mentre il client è in attesa di input. Aspettano per sempre perché nessuno sta inviando nulla. – Duck

+0

No, il comando ls non funziona ancora. Questi programmi funzionano una volta: il server attende un messaggio, lo restituisce al client, il client può chiudersi. Quando voglio inviare un altro messaggio, sia il client che il server non rispondono. – uluroki

risposta

5

Perché non solo gestire sia FIFO nel server? Semplicemente cambiando il codice per farlo, funziona correttamente.

Se si desidera effettivamente avere una relazione client-server, con un server che serve molti client diversi, i socket potrebbero essere una scelta migliore.

client.cpp

#include <stdio.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char str[BUFSIZ]; 
    printf("Input message to serwer: "); 
    scanf("%s", str); 


    /* write str to the FIFO */ 
    client_to_server = open(myfifo, O_WRONLY); 
    server_to_client = open(myfifo2, O_RDONLY); 
    write(client_to_server, str, sizeof(str)); 

    perror("Write:"); //Very crude error check 

    read(server_to_client,str,sizeof(str)); 

    perror("Read:"); // Very crude error check 

    printf("...received from the server: %s\n",str); 
    close(client_to_server); 
    close(server_to_client); 

    /* remove the FIFO */ 

    return 0; 
} 

server.cpp

#include <fcntl.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char buf[BUFSIZ]; 

    /* create the FIFO (named pipe) */ 
    mkfifo(myfifo, 0666); 
    mkfifo(myfifo2, 0666); 

    /* open, read, and display the message from the FIFO */ 
    client_to_server = open(myfifo, O_RDONLY); 
    server_to_client = open(myfifo2, O_WRONLY); 

    printf("Server ON.\n"); 

    while (1) 
    { 
     read(client_to_server, buf, BUFSIZ); 

     if (strcmp("exit",buf)==0) 
     { 
     printf("Server OFF.\n"); 
     break; 
     } 

     else if (strcmp("",buf)!=0) 
     { 
     printf("Received: %s\n", buf); 
     printf("Sending back...\n"); 
     write(server_to_client,buf,BUFSIZ); 
     } 

     /* clean buf from any data */ 
     memset(buf, 0, sizeof(buf)); 
    } 

    close(client_to_server); 
    close(server_to_client); 

    unlink(myfifo); 
    unlink(myfifo2); 
    return 0; 
} 
4

Funziona solo una volta a causa di come named pipe funzionano. Ogni volta che si usa la pipe denominata open per leggere il blocco fino a quando un altro processo lo apre per la scrittura. Quindi sei associato e il descrittore di file collega i tuoi processi. Una volta entrambe le estremità chiude quella connessione che è la fine di quel tubo. Affinché il tuo server "accetti un'altra connessione" deve spostare il open e il close dei pipe nel suo loop principale in modo che possa essere abbinato più e più volte.

Problemi correlati