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

实现聊天功能:

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
#include
#include
#include
#include
#include
#include
#include

(1).程序a实现代码

程序a.c

#include "myhead.h"
int main(){

    //判断管道1和2是否存在
    int ret = access("fifo1",F_OK);
    if(ret==-1){
        //不存在,创建管道1
        ret = mkfifo("fifo1",0664);

        if(ret == -1){
            perror("mkfifo");
            exit(0);
        }
    }

    ret = access("fifo2",F_OK);
    if(ret==-1){
        //不存在,创建管道2
        ret = mkfifo("fifo2",0664);

        if(ret == -1){
            perror("mkfifo");
            exit(0);
        }
    }

    //以只写的方式打开管道fifo1
    int fdw = open("fifo1",O_WRONLY);
    if(fdw == -1){
        perror("open");
        exit(0);
    }
    printf("打开管道成功,等待写入:\n");
    //以只读的方式打开管道fifo2
    int 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){
        //不存在,创建管道1
        ret = mkfifo("fifo1",0664);

        if(ret == -1){
            perror("mkfifo");
            exit(0);
        }
    }

    ret = access("fifo2",F_OK);
    if(ret==-1){
        //不存在,创建管道2
        ret = mkfifo("fifo2",0664);

        if(ret == -1){
            perror("mkfifo");
            exit(0);
        }
    }

    //以只读的方式打开管道fifo1
    int fdr = open("fifo1",O_RDONLY);
    if(fdr == -1){
        perror("open");
        exit(0);
    }
    printf("打开管道fifo1成功,等待读取:\n");
    //以只写的方式打开管道fifo2
    int 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也会是一样的动作。

你可能感兴趣的:(c++,c++,c语言,算法,linux)