无名管道与有名管道的区别
无名管道:
它是半双工的,具有固定的读端和写端。
只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
不是普通的文件,不属于其他任何文件系统,并且只存在于内存中。
有名管道FIFO:
FIFO可以在无关的进程之间交换数据。
FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
思路
父进程负责写,子进程负责读。
FIFO1负责存储用户a发出的消息,
FIFO2负责存储用户b发出的消息。
代码
chat_a.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>int main(){pid_t pid = fork();if (pid > 0){//a的父进程写FIFO1char *fifo1 = "./fifo1";//判断fifo1是否存在int ret = access(fifo1, F_OK);if (ret == -1){//文件不存在,需要创建ret = mkfifo(fifo1, 0664);if (ret == -1){//创建失败 perror("mkfifo error");exit(-1);}}//文件fifo1存在,以只写方式打开int fdw = open(fifo1, O_WRONLY);if (fdw == -1){perror("open error");exit(-1);}printf("a:successfully opened fifo1\n");//循环写入数据char buf[256];while (1){memset(buf, 0, sizeof(buf));//获取标准输入的数据fgets(buf, sizeof(buf), stdin);//写数据到fifo1int len = write(fdw, buf, strlen(buf));if (len == -1){perror("write error");break;}printf("\n");}close(fdw);}else if (pid == 0){//a的子进程读FIFO2char *fifo2 = "./fifo2";//判断FIFO2是否存在int ret = access(fifo2, F_OK);if (ret == -1){//文件不存在,需要创建ret = mkfifo(fifo2, 0664);if (ret == -1){//创建失败perror("mkfifo error");exit(-1); }}//文件FIFO2存在,以只读方式打开int fdr = open(fifo2, O_RDONLY);if (fdr == -1){perror("open error");exit(-1);}printf("a:successfully opened fifo2\n");//循环读数据char buf[256];while (1){memset(buf, 0, sizeof(buf));int len = read(fdr, buf, sizeof(buf));if (len <= 0){perror("read");break;}printf("b: %s\n", buf);}close(fdr);}return 0;
}
chat_b.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>int main(){pid_t pid = fork();if (pid > 0){//b的父进程写FIFO2char *fifo2 = "./fifo2";//判断文件fifo2是否存在int ret = access(fifo2, F_OK);if (ret == -1){//文件不存在,需要创建ret = mkfifo(fifo2, 0664);if (ret == -1){perror("mkfifo error");exit(-1);}}//文件fifo2存在,以只写方式打开int fdw = open(fifo2, O_WRONLY);if (fdw == -1){perror("open error");exit(-1);}printf("b:successfully opened fifo2\n");//循环写入数据char buf[256];while (1){memset(buf, 0, sizeof(buf));//获取标准输入的数据fgets(buf, sizeof(buf), stdin);//写数据到fifo2int len = write(fdw, buf, strlen(buf));if (len == -1){perror("write error");break;}printf("\n");}close(fdw);}else if (pid == 0){//b的子进程读FIFO1char *fifo1 = "./fifo1";int ret = access(fifo1, F_OK);if (ret == -1){//文件不存在,需要创建ret = mkfifo(fifo1, 0664);if (ret == -1){perror("mkfifo error");exit(-1); }}//文件FIFO1存在,以只读方式打开int fdr = open(fifo1, O_RDONLY);if (fdr == -1){perror("open error");exit(-1);}printf("b:successfully opened fifo1\n");// 循环读数据char buf[256];while (1){memset(buf, 0, sizeof(buf));int len = read(fdr, buf, sizeof(buf));if (len <= 0){perror("read");break;}printf("a: %s\n", buf);}close(fdr);}return 0;
}