运用进程间的有名管道通信,实现一个聊天的功能

news/2025/1/11 14:05:24/

实现聊天功能:

1.思路

聊天功能,必须是两个运行的程序间的通信。既A可以给B发多条信息,B也可以给A发多条信息。
(1).在程序a中的实现思路
1.判断管道fifo1和fifo2是否存在,不存在,创建管道fifo1,fifo2
2.以只写的方式打开管道fifo1,以只读的方式打开管道fifo2
3.创建子进程,因为write函数和read函数会阻塞,只能将write函数和read函数分别放在父与子进程中,循环的写读数据
(2).程序b的实现思路
1.判断管道fifo1和fifo2是否存在,不存在,创建管道fifo1,fifo2
2.以只读的方式打开管道fifo1,以只写的方式打开管道fifo2
3.创建子进程,因为write函数和read函数会阻塞,只能将write函数和read函数分别放在父与子进程中,循环的写读数据

2.实现代码

头文件myhead.h:

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

(1).程序a实现代码

程序a.c

#include "myhead.h"
int main(){//判断管道1和2是否存在int ret = access("fifo1",F_OK);if(ret==-1){//不存在,创建管道1ret = mkfifo("fifo1",0664);if(ret == -1){perror("mkfifo");exit(0);}}ret = access("fifo2",F_OK);if(ret==-1){//不存在,创建管道2ret = mkfifo("fifo2",0664);if(ret == -1){perror("mkfifo");exit(0);}}//以只写的方式打开管道fifo1int fdw = open("fifo1",O_WRONLY);if(fdw == -1){perror("open");exit(0);}printf("打开管道成功,等待写入:\n");//以只读的方式打开管道fifo2int fdr = open("fifo2",O_RDONLY);if(fdr == -1){perror("open");exit(0);}printf("打开管道成功,等待读取:\n");pid_t pid = fork();if(pid == -1){perror("fork");exit(0);}//循环的写读数据if(pid>0){//printf("a中的父进程还在");char bufw[128];while (1){memset(bufw,0,128);//获取标准输入数据fgets(bufw,128,stdin);//用fifo1的写端写入数据//printf("用fifo1的写端写入数据:%s\n",bufw);ret = write(fdw,bufw,strlen(bufw));//阻塞在这,不会运行下面的代码!!!③写数据时fgets,write函数都是阻塞函数,如果没有输入将一直阻塞在这里不往下执行,这个会带来很多坑if(ret == -1){perror("write");exit(0);}    }close(fdw);}else if(pid==0){//printf("a中的子进程还在");char bufr[128];while(1){//读管道数据memset(bufr,0,128);int retr = read(fdr,bufr,128);if(retr < 0){perror("read");break;}else if(retr==0){printf("对方已断开链接!!!");close(fdr);close(fdw);kill(getppid(), SIGTERM);break;}else{printf("buf:%s\n",bufr);}}close(fdr);}return 0;
}

(2).程序b的实现代码
程序b.c

#include "myhead.h"
int main(){//判断管道1和2是否存在int ret = access("fifo1",F_OK);if(ret==-1){//不存在,创建管道1ret = mkfifo("fifo1",0664);if(ret == -1){perror("mkfifo");exit(0);}}ret = access("fifo2",F_OK);if(ret==-1){//不存在,创建管道2ret = mkfifo("fifo2",0664);if(ret == -1){perror("mkfifo");exit(0);}}//以只读的方式打开管道fifo1int fdr = open("fifo1",O_RDONLY);if(fdr == -1){perror("open");exit(0);}printf("打开管道fifo1成功,等待读取:\n");//以只写的方式打开管道fifo2int fdw = open("fifo2",O_WRONLY);if(fdw == -1){perror("open");exit(0);}printf("打开fifo2管道成功,等待写入:\n");pid_t pid = fork();if(pid == -1){perror("fork");exit(0);}//循环的写读数据//父子进程if(pid > 0){//读管道数据char bufr[128];while(1){memset(bufr,0,128);int retr = read(fdr,bufr,128);if(retr < 0){perror("read");break;}else if(retr==0){printf("对方已断开链接!!!\n");//发送SIGTERM信号给子进程kill(pid, SIGTERM);close(fdr);close(fdw);exit(0);}{printf("buf:%s\n",bufr);}}close(fdr);}else if(pid == 0){//写管道数据char bufw[128];while(1){memset(bufw,0,128);//获取标准输入数据fgets(bufw,128,stdin);//写入数据ret = write(fdw,bufw,strlen(bufw));if(ret == -1){perror("write");exit(0);}}close(fdw);} return 0;
}

最后:

在两个不同的会话中打开两个程序,就可以实现聊天功能。
另外我还实现了当a退出程序的时候,b会接收a退出的消息,并且b也会退出程序。当b退出程序,a也会是一样的动作。


http://www.ppmy.cn/news/258585.html

相关文章

uniapp的H5真机调试ios音频播放没声音

安卓的手机音频播放没问题&#xff0c;ios系统“浏览器调试”也有声音&#xff0c;发布到服务器&#xff0c;苹果手机&#xff0c;播放没声音的解决方式如下&#xff1a; 第一步&#xff1a; npm install weixin-js-sdk 第二步&#xff1a; <script> import w…

当“代码农”遇上“码农”:揭秘主干开发的那些事儿 | 京东云技术团队

前段时期我负责部门内部主干开发落地相关事宜&#xff0c;这个过程中&#xff0c;也真真切切的体会到了多人开发过程中&#xff0c;面对特性分支管理中&#xff0c;大家遇到的一些困扰&#xff0c;尤其面对敏捷迭代的开发方式&#xff0c;合并冲突&#xff0c;集成测试&#xf…

路由器端口介绍

路由器所在的网络位置比较复杂&#xff0c;既可是内部子网边缘&#xff0c;也可位于内、外部网络边缘。同时为了实现强大的适用性&#xff0c;它需要连接各种网络&#xff0c;这样&#xff0c;它的接口也就必须多种多样。对于这些&#xff0c;不要说一般的网络爱好者&#xff0…

路由器端口镜像

端口镜像&#xff08;port Mirroring&#xff09;功能通过在交换机或路由器上&#xff0c;将一个或多个源端口的数据流量转发到某一个指定端口来实现对网络的监听&#xff0c;指定端口称之为“镜像端口”或“目的端口”&#xff0c;在不严重影响源端口正常吞吐流量的情况下&…

水星路由器DNS服务器未响应,为什么新版水星路由器不能上网

摘 要 不少使用水星路由器的用户,经常会遇到自己的水星路由器连不上网的问题。不管你的水星路由器是刚刚设置后不能上网;还是之前上网正常,现在不能上网了。觉得你都应该按照下面的步骤进行排查: 1、检查宽带是否正 水星路由器设置好了还是不能上网怎么办? 为什么我的水星…

LeetCode-0607

90. 子集 II(中等) 思路&#xff1a;在深搜的过程中不断加入子集合&#xff0c;并且同层次&#xff08;同一层for&#xff09;的搜索里面去掉重复元素 class Solution {private List<List<Integer>> res;public List<List<Integer>> subsetsWithDup(…

合格的电子工程师需要掌握的知识和技能-摘抄

第一部分&#xff1a;硬件知识一、 数字信号1、 TTL和带缓冲的TTL信号2、 RS232和定义3、 RS485/422&#xff08;平衡信号&#xff09;4、 干接点信号二、 模拟信号视频1、 非平衡信号2、 平衡信号三、 芯片1、 封装2、 74073、 74044、 74005、 74LS5736、 ULN20037、 74LS244…

从初学者到电子工程师

第一课&#xff1a;51单片机最小系统 实际上&#xff0c;51单片机核心外围电路是很简单的&#xff0c;一个单片机&#xff0b;一个看门狗&#xff0b;一个晶振&#xff0b;2个磁片电容&#xff1b; 1. 单片机&#xff1a;atmel的89C51系列、winbond的78E52系列&#xff0c;还有…