实现聊天功能:
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也会是一样的动作。