简体   繁体   中英

using named pipes to implement chat in C

I have created two pipes for client and server using FIFO named pipes. Then I tried to execute the communication between client and server. The communication works when sending messages from client to server but not vice versa. kindly help.

here are the three codes :

fifo.c (to create the pipes)

#include<stdio.h> 
#include<fcntl.h>
#include<stdlib.h>
main()
{
int file1,file2;
int fd;
char str[256];
char temp[4]="how";
char temp1[4];
file1 = mkfifo("fifo_server",0666); 
if(file1<0) {
 printf("Unable to create a fifo");
 exit(-1);
 }

file2 = mkfifo("fifo_client",0666);

if(file2<0) {
 printf("Unable to create a fifo");
 exit(-1);
 }
printf("fifos server and child created successfuly\n ");
}

server.c (to send and receive from client)

#include<stdio.h> 
#include<fcntl.h>
#include<stdlib.h>
main()
{
FILE *file1;
int fifo_server,fifo_client;
char *choice;
char *buf;
if(fork() == 0)
    {
        while(1)
        {   
        fifo_server = open("fifo_server",O_RDWR);
        if(fifo_server<1) {
         printf("Error opening file");
         }

        read(fifo_server,choice,sizeof(choice));
        printf("%s\n",choice);
        close(fifo_server);
        }
        //sleep(3);


    }
else
{
    while(1)
    {   
        buf = malloc(10*sizeof(char));  
        scanf("%s",buf);

        fifo_client = open("fifo_client",O_RDWR);

        if(fifo_client<1) {
         printf("Error opening file");
         }



         write(fifo_client,buf,sizeof(buf)); 
        close(fifo_client);

    }
}

close(fifo_server);
close(fifo_client);
}

client.c (to send and receive from server)

#include<stdio.h> 
#include<fcntl.h>
#include<stdlib.h>
main()
{
 FILE *file1;
 int fifo_server,fifo_client;
 char str[256];
 char *buf;
 char *choice;
 printf("Welcome to chat\n\n");
if(fork() == 0)
    {   

    while(1)
    {
         choice = malloc(10*sizeof(char));
         scanf("%s",choice);

         fifo_server=open("fifo_server",O_RDWR);
         if(fifo_server < 1) {
          printf("Error in opening file");
          exit(-1);
          }

         write(fifo_server,choice,sizeof(choice));

         //sleep(10);   
    }    


    }
 else{
    while(1)
    {


        fifo_client = open("fifo_client",O_RDWR);
        if(fifo_client<1) {
         printf("Error opening file");
         exit(1);
         }

        read(fifo_client,choice,sizeof(choice));
        printf("%s\n",choice);

        /*      
        fifo_client=open("fifo_client",O_RDWR);

         if(fifo_client < 0) {
          printf("Error in opening file");
          exit(-1);
          }

         buf=malloc(10*sizeof(char));
         read (fifo_client,buf,sizeof(buf));
         printf("\n %s***\n",buf);
        */
    }

}

close(fifo_server); 
close(fifo_client);  
}

Some observations:

  • You read to choice but you never allocate memory to it.
  • Don't malloc() and open()/close() in every iteration, instead use static character buffer like buf[512] for read()s from network and write()s as well (write() strnlen() bytes/chars).

For example, instead of:

char *buf;
char *choice;
printf("Welcome to chat\n\n");
if(fork() == 0) {   
  while(1) {
    choice = malloc(10*sizeof(char));
    scanf("%s",choice);

    fifo_server=open("fifo_server",O_RDWR);
    if(fifo_server < 1) {
      printf("Error in opening file");
      exit(-1);
    }
   write(fifo_server,choice,sizeof(choice));
}

Do something like:

char buf[512];
if(fork() == 0) {
  fifo_server = open("fifo_server", O_RDWR);
  if(fifo_server < 1) {
      printf("Error in opening file");
      exit(-1);
  }
  while(1) {
    fgets(buf, 512, stdin);
    write(fifo_server, buf, strnlen(buf, 512));
    /* here should be checks for number of bytes/chars written */
  }
}

Just finished writing a server and client side program that seems to be working! I created the pipes in terminal in the folder. They are named myPipeC and myPipeS (For client and server respectively).

This is client.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(int argc, const char * argv[]) {
    int myPipeC = open("myPipeC", O_RDWR);
    int myPipeS = open("myPipeS",O_RDWR);
    pid_t cpid;
    char buf[255];
    char send[255];
    int n;
    int saveIn = dup(fileno(stdin));
    int saveOut = dup(fileno(stdout));
    while(1) {
        if ((cpid = fork()) == 0 ) {
            while(1){
                while((n=read(myPipeC,&buf,255)) > 0){
                    write(fileno(stdout), &buf, n*sizeof(char));
                }
            }
        } else {
            while(1){
                fgets(send, 255,stdin);
                int len = strlen(send);
                write(myPipeS,send,(len+1)*sizeof(char));
            }
        }
    }
    close(myPipeC);
    close(myPipeS);
    fflush(stdin);
    fflush(stdout);
    dup2(saveIn,fileno(stdin));
    dup2(saveOut, fileno(stdout));
    exit(EXIT_SUCCESS);
} 

server.c

int main(int argc, const char * argv[]) {
    int myPipeC = open("myPipeC", O_RDWR);
    int myPipeS = open("myPipeS",O_RDWR);
    pid_t cpid;
    char buf[255];
    char send[255];
    int n;
    int saveIn = dup(fileno(stdin));
    int saveOut = dup(fileno(stdout));
    while(1) {
        if ((cpid = fork()) == 0 ) {
            while(1){
                while((n=read(myPipeS,&buf,255)) > 0){
                     write(fileno(stdout), &buf, n*sizeof(char));
                }
            }
        } else {
            while(1){
                fgets(send, 255,stdin);
                int len = strlen(send);
                write(myPipeC,send,(len+1)*sizeof(char));
            }
        }
    }
    close(myPipeC);
    close(myPipeS);
    fflush(stdin);
    fflush(stdout);
    dup2(saveIn,fileno(stdin));
    dup2(saveOut, fileno(stdout));
    exit(EXIT_SUCCESS);
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM