Linux程序设计之有名管道实现简单版聊天系统

  1. 利用有名管道实现两个系统之间的通信,同时,在各自的系统中分别利用父子进程实现数据的读写功能。

  1. 代码:

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

int main()
{
    //1.判断管道文件是否已经存在
    int ret = access("fifo1",F_OK);
    if(ret == -1)
    {
        //管道文件不存在
        printf("管道文件fifo1不存在,正在创建管道文件\n");
        int res = mkfifo("fifo1",0664);

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

    ret=access("fifo2",F_OK);
    if(ret == -1)
    {
        printf("管道文件fifo2不存在,正在创建管道文件 \n");
        int res = mkfifo("fifo2",0664);
        if(res == -1)
        {
            perror("mkfifo");
            exit(0);
        }
    }

    //2.以只写的方式打开管道文件fifo1
    pid_t fd1 = open("fifo1",O_WRONLY);
    if(fd1 == -1)
    {
        perror("open");
        exit(0);
    }

    //3.以只读的方式打开管道文件fifo2
    pid_t fd2 = open("fifo2",O_RDONLY);
    if(fd2 == -1)
    {
        perror("open");
        exit(0);
    }

    char buf[128]={0};
    //4.父子进程循环的读、写数据

    pid_t ret1 = fork();
    if (ret1 == -1)
    {
       perror("fork");
       exit(0);
    }

    //父进程写数据
    if(ret1 > 0)
    {
        while(1)
        {
            //清空数据
            memset(buf,0,strlen(buf));
            //写入数据
            fgets(buf,128,stdin);
            printf("chatA send: %s \n",buf);
            int len1 = write(fd1,buf,strlen(buf));
        }
    }

    //子进程读数据
    if(ret1 == 0)
    {
       while(1)
       {
            //清空数据
            memset(buf,0,strlen(buf));
            
             //读取数据
            int len2 = read(fd2,buf,sizeof(buf));
            if(len2 <= 0)
            {
                perror("read");
                break;
            }

            printf("chatA receive: %s",buf);
       } 
    }

    //5.关闭文件
    close(fd1);
    close(fd2);

    return 0;
}
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    //1.判断管道文件是否已经存在
    int ret = access("fifo1",F_OK);
    if(ret == -1)
    {
        //管道文件不存在
        printf("管道文件fifo1不存在,正在创建管道文件\n");
        int res = mkfifo("fifo1",0664);

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

    ret=access("fifo2",F_OK);
    if(ret == -1)
    {
        printf("管道文件fifo2不存在,正在创建管道文件 \n");
        int res = mkfifo("fifo2",0664);
        if(res == -1)
        {
            perror("mkfifo");
            exit(0);
        }
    }

    //2.以只读的方式打开管道文件fifo1
    pid_t fd1 = open("fifo1",O_RDONLY);
    if(fd1 == -1)
    {
        perror("open");
        exit(0);
    }

    //3.以只写的方式打开管道文件fifo2
    pid_t fd2 = open("fifo2",O_WRONLY);
    if(fd2 == -1)
    {
        perror("open");
        exit(0);
    }

    char buf[128] = {0};
    //4.父子进程循环的读、写数据

    pid_t ret1 = fork();
    if (ret1 == -1)
    {
       perror("fork");
       exit(0);
    }

    //父进程读数据
    if(ret1 > 0)
    {
        while(1)
        {
            //清空数据
            memset(buf,0,strlen(buf));

            //读取数据
            int len2 = read(fd1,buf,sizeof(buf));
            if(len2 <= 0)
            {
                perror("read");
                break;
            }

            printf("chatB receive: %s",buf); 
        }
    }

    //子进程写数据
    if(ret1 == 0)
    {
        while(1)
        {
            //清空数据
            memset(buf,0,strlen(buf));

            //写入数据
            fgets(buf,128,stdin);
            printf("chatB send: %s",buf);
            int len1 = write(fd2,buf,strlen(buf)); 
        }
    }

    //5.关闭文件
    close(fd1);
    close(fd2);

    return 0;
}
  1. 运行结果:

4.总结:read和write函数在运行时是阻塞的,当我们从终端上输入数据write,其实是放在数据缓冲区中,只有当管道的另以端read时,数据才会被写入到管道中。为了实现两个系统之间的实时通信,分别各自利用父子进程完成数据的读写功能。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值