使用命名管道在C中实现聊天

时间:2013-12-08 20:09:54

标签: c linux client-server chat mkfifo

我使用FIFO命名管道为客户端和服务器创建了两个管道。然后我尝试执行客户端和服务器之间的通信。从客户端向服务器发送消息时通信有效,反之亦然。请帮助。

以下是三个代码:

fifo.c(创建管道)

#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(从客户端发送和接收)

#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(从服务器发送和接收)

#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);  
}

2 个答案:

答案 0 :(得分:1)

一些观察结果:

  • 你读到了choice,但你永远不会为它分配内存。
  • 在每次迭代中不要使用malloc()和open()/ close(),而是使用静态字符缓冲区(如buf[512])来读取网络中的read()和write()(write()) strnlen()bytes / chars)。

例如,而不是:

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));
}

做类似的事情:

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 */
  }
}

答案 1 :(得分:0)

刚刚编写了一个似乎正在运行的服务器和客户端程序!我在文件夹中的终端创建了管道。它们被命名为myPipeC和myPipeS(分别用于客户端和服务器)。

这是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);
}