Home > Software design >  client-server application using fifos
client-server application using fifos

Time:10-22

I'm trying to write a client-server application in C using 2 fifos (client_to_server and server_to_client). A version of the app where the client writes a command to the server who reads it works well, but when I add in client the lines in order to read the answer from the server it doesn't work anymore: the server gets blocked in reading the command from the client (as if there is nothing in client_to_server fifo, although the client written in it). What could be the problem in this case?

client.c:

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

#define MAX_BUF_CMD 100


FILE* open_fifo_send(char *nume_fifo);
FILE* open_fifo_rec(char *nume_fifo);
void send_command(FILE *c2s);
void rec_answer(char* str, FILE *s2c);

int main()
{
    FILE *c2s, *s2c;
    char ans[100];
    char cmd[100];

    c2s=open_fifo_send("canal_c2s");
    s2c=open_fifo_rec("canal_s2c");
    printf("[client] Conectare la server reusita!\n");

    send_command(c2s);
    rec_answer(ans, s2c); /*without this line works fine */
    

    

    return 0;
}



FILE* open_fifo_send(char *nume_fifo)
{
    int fd;
    //FILE* c2s;
    if(-1==(fd=open(nume_fifo, O_WRONLY)))
    {
        perror("[client]Eroare la open canal_c2s");
        exit(2);
    }
    return fdopen(fd, "w");
}
FILE* open_fifo_rec(char *nume_fifo)
{
    int fd;
    //FILE* s2c;
    if(-1==(fd =open(nume_fifo, O_RDONLY)))
    {
        perror("[client]Eroare la open canal_s2c");
        exit(2);
    }
    return fdopen(fd, "r");
}

void send_command(FILE *c2s)
{
    char cmd[MAX_BUF_CMD];
    int bytes;
    printf("Da-ti o comanda:\n");
    fgets(cmd,100,stdin);
    if(fputs(cmd, c2s)==EOF)
    {
        perror("[client] Eroare la scrirea in canal_c2s");
        exit(3);
    }
    printf("[client]Am dat comanda: %s\n", cmd);
}

void rec_answer(char *str,FILE *s2c)
{
    int lungime_raspuns;
    fgets(str,100, s2c);
}
server.c

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

#define MAX_BUF 100

void create_fifo_client_to_server();
void create_fifo_server_to_client();
FILE *open_fifo_rec(char *nume_fifo);
FILE *open_fifo_send(char *nume_fifo);
void rec_command(char* str, FILE* fd);
void send_answer(FILE *fd);

int main()
{
    FILE *c2s, *s2c;
    char cmd[MAX_BUF];

    create_fifo_client_to_server();
    create_fifo_server_to_client();
    c2s=open_fifo_rec("canal_c2s");
    s2c=open_fifo_send("canal_s2c");
    printf("[server] Clientul s-a conectat\n");
        

    rec_command(cmd, c2s);
    printf("Am primit comanda: %s\n", cmd);
    fprintf(s2c, "message to client");


    unlink("canal_c2s"); //remove fifo
    unlink("canal_s2c");
    return 0;
}

void create_fifo_client_to_server()
{
    if(-1==mkfifo("canal_c2s", 0666)){
        perror("[server]Eroare la mkfifo c2s");
        exit(1);
    }
}

void create_fifo_server_to_client()
{
    if(-1==mkfifo("canal_s2c", 0666)){
        perror("[server]Eroare la mkfifo s2c");
        exit(1);
    }
}

FILE* open_fifo_rec(char *nume_fifo)
{
    int fd;
    //FILE *c2s;
    if(-1==(fd=open(nume_fifo, O_RDONLY)))
    {
        perror("[server]Eroare la open canal_c2s");
        exit(2);
    }
    return fdopen(fd, "r");
}

FILE* open_fifo_send(char * nume_fifo)
{
    int fd;
    //FILE *s2c;
    if(-1==(fd=open(nume_fifo, O_WRONLY)))
    {
        perror("[server]Eroare la open canal_s2c");
        exit(2);
    }
    return fdopen(fd,"w");
}

void rec_command(char *str, FILE *c2s)
{
    fscanf(c2s, "%s", str);
}

void send_answer(FILE *s2c)
{
    fprintf(s2c, "asdgf");
}

CodePudding user response:

You are using fputs to send data to the server. That means that the data could stay in a local buffer until the buffer is full or you explicitely flush it. When you do not wait for the answer but exit from the client, the fifo is implicitely flushed and closed, causing the server to recieve something. But if you start waiting in the client without a prior flush, you end with a deadlock.

But remember: pipes were invented for single way communications. If you want 2 way communications with acknowlegements and/or synchronizations, you should considere using sockets.

  • Related