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

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

无名管道

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

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

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

有名管道****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;
}
相关推荐
段帅龙呀25 分钟前
Redis构建缓存服务器
服务器·redis·缓存
乌鸦不像写字台1 小时前
【docker部署】在服务器上使用docker
服务器·docker·容器
牧以南歌〆2 小时前
在Ubuntu主机中修改ARM Linux开发板的根文件系统
linux·arm开发·驱动开发·ubuntu
董董灿是个攻城狮2 小时前
5分钟搞懂什么是窗口注意力?
算法
Dann Hiroaki2 小时前
笔记分享: 哈尔滨工业大学CS31002编译原理——02. 语法分析
笔记·算法
Antonio9153 小时前
【音视频】HLS简介与服务器搭建
运维·服务器·音视频
夜月yeyue3 小时前
设计模式分析
linux·c++·stm32·单片机·嵌入式硬件
kfepiza4 小时前
Debian的`/etc/network/interfaces`的`allow-hotplug`和`auto`对比讲解 笔记250704
linux·服务器·网络·笔记·debian
无妄-20244 小时前
软件架构升级中的“隐形地雷”:版本选型与依赖链风险
java·服务器·网络·经验分享
qqxhb4 小时前
零基础数据结构与算法——第四章:基础算法-排序(上)
java·数据结构·算法·冒泡·插入·选择