【Linux】有名管道实现简单版聊天功能

news2024/9/20 5:54:57

目录

  • 有名管道实现简单版聊天功能

橙色

有名管道实现简单版聊天功能

创建两个.c文件,一个是chata.c,一个是chatb.c

chata.c文件内容如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

int main() {

    // 1.判断有名管道文件是否存在
    int ret = access("fifo1", F_OK);
    if(ret == -1) {
        // 文件不存在
        printf("管道不存在,创建对应的有名管道\n");
        ret = mkfifo("fifo1", 0664);
        if(ret == -1) {
            perror("mkfifo");
            exit(0);
        }
    }

    ret = access("fifo2", F_OK);
    if(ret == -1) {
        // 文件不存在
        printf("管道不存在,创建对应的有名管道\n");
        ret = mkfifo("fifo2", 0664);
        if(ret == -1) {
            perror("mkfifo");
            exit(0);
        }
    }

    // 2.以只写的方式打开管道fifo1
    int fdw = open("fifo1", O_WRONLY);
    if(fdw == -1) {
        perror("open");
        exit(0);
    }
    printf("打开管道fifo1成功,等待写入...\n");

    // 3.以只读的方式打开管道fifo2
    int fdr = open("fifo2", O_RDONLY);
    if(fdr == -1) {
        perror("open");
        exit(0);
    }
    printf("打开管道fifo2成功,等待读取...\n");
	
	//之所以需要两个进程,是因为在一个进程中,由于while死循环,该进程向一个有名管道中写入内容后,
	//就必须在另一个管道读取一次内容,如果写入而没有读取(也就是对方写入)的话,就会阻塞在读取这里
	//呈现的效果就是a向b先发送多条消息,但b仅能接收到一条,在b回复后,a像b发送的除第一条消息外剩下的消息才会才发送过来
	//所以需要两个进程分别执行在两个有名管道中读和写的操作。
    pid_t pid = fork();

    if(pid>0){
        char buf[128];
         while(1) {
        memset(buf, 0, 128);
        // 获取标准输入的数据
        fgets(buf, 128, stdin);
        // 写数据
        ret = write(fdw, buf, strlen(buf));
        if(ret == -1) {
            perror("write");
            exit(0);
        }       
    }
    close(fdw);
    }

    else{
        char buf[128];
        while(1) {
        memset(buf, 0, 128);
        
        // 5.读管道数据
        memset(buf, 0, 128);
        ret = read(fdr, buf, 128);
        if(ret <= 0) {
            perror("read");
            break;
        }
        printf("buf: %s\n", buf);
    }
    // 6.关闭文件描述符
    close(fdr);
    }
    
    // 6.关闭文件描述符
    close(fdr);
    close(fdw);

    return 0;
}

chatb.c文件内容如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

int main() {

    int ret=access("fifo1",F_OK);
    if(ret==-1){
        printf("管道不存在,创建对应的有名管道\n");
        ret=mkfifo("fifo1",0664);
        if(ret==-1){
            perror("fifo1");
            exit(0);
        }  
    }
    ret=access("fifo2",F_OK);
    if(ret==-1){
        printf("管道不存在,创建对应的有名管道\n");
        ret=mkfifo("fifo2",0664);
        if(ret==-1){
        perror("fifo2");
        exit(0);
        }
    }

    int fdr=open("fifo1",O_RDONLY);
    if(fdr==-1){
        perror("open");
        exit(0);
    }
    printf("打开管道fifo1成功,等待读取...\n");
    int fdw=open("fifo2",O_WRONLY);
    if(fdw==-1){
        perror("open");
        exit(0);
    }
    printf("打开管道fifo2成功,等待写入...\n");

    pid_t pid = fork();

    if(pid>0){
        char buf[128];
        while (1){
            memset(buf,0,128);
            ret=read(fdr,buf,sizeof(buf));
            if(ret<=0){
                perror("read");
                break;
            }
        printf("buf:%s\n",buf);
        } 
    close(fdr);
    }

    else{
        char buf[128];
        while (1){
            memset(buf,0,128);
            fgets(buf,128,stdin);
            ret=write(fdw,buf,strlen(buf));
            if(ret==-1){
                perror("write");
                exit(0);
            }
        } 
        close(fdw);
    }

    return 0;
}

在xshell中编译两个文件得到两个可执行文件chata和chatb,接着在xshell的两个窗口分别执行chata和chatb两个可执行程序,即可实现对话。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/536713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-基础IO

一、C语言文件IO 1、C库函数介绍 打关文件fopen/fclose&#xff1a; FILE * fopen(const char* filename, const char* mode); int fclose (FILE* stream );文件打开方式&#xff1a; 读写函数fread/fwrite&#xff1a; size_t fread( void *buffer, size_t size, size_t cou…

刷题day66:目标和

题意描述&#xff1a; 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 &#xff0c;在 1 之前添…

Kibana 的安装

1. 简介 Kibana 是一个开源的分析与可视化平台&#xff0c;可以用 Kibana 搜索、查看存放在 Elasticsearch 中的数据&#xff0c;就跟谷歌的 elasticsearch head 插件类似&#xff0c;但 Kibana 与 Elasticsearch 的交互方式是各种不同的图表、表格、地图等&#xff0c;直观的…

物联网和边缘计算:如何将数据处理和决策推向设备边缘

第一章&#xff1a;引言 当我们谈论物联网&#xff08;IoT&#xff09;时&#xff0c;我们通常指的是将各种设备连接到互联网&#xff0c;并通过数据交换来实现智能化的网络。然而&#xff0c;传统的物联网模型通常涉及将数据发送到云端进行处理和分析。然而&#xff0c;随着技…

5月第2周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年5月8日-5月14日飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B站…

【js】原生input框及下拉框数据联动( 列如: 输入框输入 3,下拉框里的选项值则为:1,2,3)

需求 输入框输入 数字 下拉框要显示对应的数字 列如: 输入框输入 13 下拉框里的选项值则为&#xff1a;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;7&#xff0c;8&#xff0c;9&#xff0c;10&#xff0c;11&#xff0c;12&#xff0c;…

【数据结构 -- C语言】 双向带头循环链表的实现

目录 1、双向带头循环链表的介绍 2、双向带头循环链表的接口 3、接口实现 3.1 开辟结点 3.2 创建返回链表的头结点 3.3 判断链表是否为空 3.4 打印 3.5 双向链表查找 3.6 双向链表在pos的前面进行插入 3.6.1 头插 3.6.2 尾插 3.6.3 更新头插、尾插写法 3.7 双向链…

springBoot中使用redis实现分布式锁实例demo

首先 RedisLockUtils工具类 package com.example.demo.utils;import org.junit.platform.commons.util.StringUtils; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.red…

【最短路径 本质模板】【最短路径问题 本质 Dijkstra 和 spfa】收藏本篇,遇到最短路问题,来看看模板和思路

也就是走过的节点&#xff0c;还可以再走 但是dij走过的不能再走了 这是本章的精髓&#xff0c;大家往下看 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章…

关于deeplabv3的输出维度与类别预测的对应关系

这里用到的代码是&#xff1a;DeepLabV3源码讲解(Pytorch)_哔哩哔哩_bilibili 背景说明&#xff1a;自己做了一个数据集&#xff0c;已经训练完毕&#xff0c;一共7类零食&#xff0c;加背景算8类。 前面的代码省略了model.eval() # 进入验证模式with torch.no_grad():# init …

WordPress 技巧:WordPress设置媒体文件的默认链接本身方法

当我们在 WordPress 后台上传文件&#xff0c;并添加到内容中得时候&#xff0c;默认媒体文件是链接到文件本身&#xff0c;这个是很烦人的&#xff0c;有时候我们只是想在文章内容中插入一张图片&#xff0c;而不想给这张图片加上任何链接&#xff0c;我们怎么做呢&#xff1f…

动态主机配置协议 DHCP

文章目录 1 概述2 DHCP2.1 工作原理2.2 报文类型 3 扩展3.1 网工软考真题 1 概述 #mermaid-svg-ZESmHWHRC6kYroqm {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZESmHWHRC6kYroqm .error-icon{fill:#552222;}#merm…

Java EE 进阶--多线程(二)

目录 一、JUC(java.util.concurrent) 的常见类 1.1 信号量 Semaphore 1.2 CountDownLatch 1.3 CyclicBarrier -循环栅栏 二、线程安全的集合类 2.1 多线程环境使用 ArrayList 2.2 多线程环境使用队列 2.3 多线程环境使用哈希表 三、死锁 3.1 死锁是什么 3.2 如何避免死…

Linux文本三剑客之sed

Linux文本三剑客之sed 一、sed简介二、工作流程三、sed的常见用法1、常见的sed命令选项2、常见的操作3、基本用法实例3.1 sed查询3.2 sed删除3.3 sed替换sed ‘s/旧字符/新字符/’ &#xff1a;替换每行匹配到的第一个旧字符3.4 sed插入 一、sed简介 sed&#xff08;Stream ED…

Chrome浏览器竟然也可以用ChatGPT了!

最近这段时间想必 和我一样&#xff0c;都被chatGPT刷屏了。 在看到网上给出的一系列chatGPT回答问题的例子和自己亲自体验之后&#xff0c;的确发现它效果非常令人惊艳。 chatGPT的火热程度在开源社区也有很明显的体现&#xff0c;刚推出不久&#xff0c;围绕chatGPT的开源项…

Redis:发布订阅

发布订阅到底是什么功能&#xff1f; 在CSDN这个app中有一个关注的功能&#xff0c;其实这个功能与redis的发布订阅有着异曲同工之处 订阅就相当于关注&#xff0c;关注之后&#xff0c;就相当于加入博主的专属的频道里&#xff0c;只要博主在这个频道里发布了什么信息&#…

VMware虚拟机安装OpenEuler欧拉系统

原文地址&#xff1a;https://program-park.top/2023/05/17/linux_7/ OpenEuler 镜像下载&#xff1a;https://www.openeuler.org/zh/download/   我这里以x86_64架构为示例&#xff0c;使用的23.03版本&#xff1a; 准备好镜像文件&#xff1a; 创建新虚拟机&#xff1a; 选…

HBuilder开发uniapp添加android的模拟器的方法

我们知道使用uniapp开发多端app非常方便&#xff0c;开发过程中的模拟器也可以提高我们测试代码的效率。但我们按uniapp官网的方法&#xff0c;上google的官网下载模拟器&#xff0c;往往非常不方便。 下面我们来看一下使用其他模拟器的方法。 我们知道android开发中&#xf…

Java生成jni.h头文件,java调用C方法 图文详解

环境搭建 1. android studio2021.2.1 2. JDK版本1.8 一、创建一个android项目 File ——> New ——> New Project ——> Empty Activity 创建后如下图所示 二、创建一个java调用C的类 2.1 java类命名为JNITest&#xff0c;创建一个两数之和的方法sums 大概需求…