【操作系统】操作系统课后作业-聊天程序

无名管道与有名管道的区别

无名管道

它是半双工的,具有固定的读端和写端。

只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

不是普通的文件,不属于其他任何文件系统,并且只存在于内存中。

有名管道****FIFO

FIFO可以在无关的进程之间交换数据。

FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

思路

父进程负责写,子进程负责读。

FIFO1负责存储用户a发出的消息,

FIFO2负责存储用户b发出的消息。

代码

chat_a.c

cpp 复制代码
#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的父进程写FIFO1
        char *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);
            //写数据到fifo1
            int len = write(fdw, buf, strlen(buf));
            if (len == -1){
                perror("write error");
                break;
            }
            printf("\n");
        }
        close(fdw);
    }
    else if (pid == 0)
    {
        //a的子进程读FIFO2
        char *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

cpp 复制代码
#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的父进程写FIFO2
        char *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);
            //写数据到fifo2
            int len = write(fdw, buf, strlen(buf));
            if (len == -1)
            {
                perror("write error");
                break;
            }
            printf("\n");
        }
        close(fdw);
    }
    else if (pid == 0)
    {
        //b的子进程读FIFO1
        char *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;
}
相关推荐
weixin_395448916 分钟前
main.c_cursor_0202
前端·网络·算法
senijusene12 分钟前
数据结构与算法:队列与树形结构详细总结
开发语言·数据结构·算法
杜家老五13 分钟前
综合实力与专业服务深度解析 2026北京网站制作公司六大优选
数据结构·算法·线性回归·启发式算法·模拟退火算法
小徐敲java14 分钟前
(运维)1Panel服务器面板Docker部署
运维·服务器·docker
goxingman35 分钟前
在 Linux 中查看磁盘运行占用(I/O 使用率)
linux·运维·chrome
STCNXPARM35 分钟前
Linux camera之Media子系统
linux·camera·v4l2·media子系统
小天源36 分钟前
XShell一台控制多台操作详情
linux·运维·服务器
xu_yule37 分钟前
网络和Linux网络-13(高级IO+多路转接)五种IO模型+select编程
linux·网络·c++·select·i/o
2301_7657031444 分钟前
C++与自动驾驶系统
开发语言·c++·算法
Ll13045252981 小时前
Leetcode二叉树 part1
b树·算法·leetcode